mirror of
https://github.com/storytold/placeholder-artcraft.git
synced 2026-10-30 09:16:49 +00:00
mirror repo (WIP)
Need to remove secrets before entire repo can be made public.
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
|
||||
export interface ArtcraftGetCreditsSuccess extends CommandResult {
|
||||
payload: ArtcraftGetCreditsPayload;
|
||||
}
|
||||
|
||||
export interface ArtcraftGetCreditsPayload {
|
||||
free_credits: number,
|
||||
monthly_credits: number,
|
||||
banked_credits: number,
|
||||
sum_total_credits: number,
|
||||
}
|
||||
|
||||
export const ArtcraftGetCredits = async () : Promise<ArtcraftGetCreditsSuccess> => {
|
||||
try {
|
||||
return await invoke("storyteller_get_credits_command") as ArtcraftGetCreditsSuccess;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
|
||||
export interface ArtcraftGetSubscriptionSuccess extends CommandResult {
|
||||
payload: ArtcraftGetSubscriptionPayload;
|
||||
}
|
||||
|
||||
export interface ArtcraftGetSubscriptionPayload {
|
||||
active_subscription?: ActiveSubscriptionInfo
|
||||
}
|
||||
|
||||
export interface ActiveSubscriptionInfo {
|
||||
subscription_token: string,
|
||||
product_slug: string,
|
||||
namespace: string,
|
||||
next_bill_at?: string,
|
||||
subscription_end_at?: string,
|
||||
}
|
||||
|
||||
export const ArtcraftGetSubscription = async () : Promise<ArtcraftGetSubscriptionSuccess> => {
|
||||
try {
|
||||
return await invoke("storyteller_get_subscription_command") as ArtcraftGetSubscriptionSuccess;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
export enum CommandSuccessStatus {
|
||||
Success = "success",
|
||||
}
|
||||
|
||||
export enum CommandErrorStatus {
|
||||
BadRequest = "bad_request",
|
||||
Unauthorized = "unauthorized",
|
||||
ServerError = "server_error",
|
||||
}
|
||||
|
||||
export type CommandStatus = CommandSuccessStatus | CommandErrorStatus;
|
||||
|
||||
export interface CommandResult {
|
||||
status: CommandStatus;
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
import { ImageModel } from "@storyteller/model-list";
|
||||
|
||||
export interface EnqueueContextualEditImageRequest {
|
||||
|
||||
/// The model to use.
|
||||
model?: ImageModel | EnqueueContextualEditImageModel;
|
||||
|
||||
/// If set, this is the first image in the contextual image set.
|
||||
/// This gets submitted along with `image_media_tokens` and will
|
||||
// be prompt engineered by Tauri.
|
||||
scene_image_media_token?: string;
|
||||
|
||||
/// Images to use for the image edit.
|
||||
/// The first image is typically a 2D canvas or 3D stage, but doesn't have to be.
|
||||
/// There must be at least one image.
|
||||
image_media_tokens?: string[];
|
||||
|
||||
/// The user's image generation prompt.
|
||||
prompt?: string;
|
||||
|
||||
/// Turn off the system prompt.
|
||||
disable_system_prompt?: boolean;
|
||||
|
||||
/// Number of images to generate.
|
||||
image_count?: number;
|
||||
|
||||
aspect_ratio?: EnqueueContextualEditImageSize;
|
||||
|
||||
image_quality?: EnqueueContextualEditImageQuality;
|
||||
}
|
||||
|
||||
|
||||
// Shape of request sent to Tauri
|
||||
// (We do some transformations from the public-facing request object.)
|
||||
interface RawEnqueueContextualEditImageRequest {
|
||||
model?: EnqueueContextualEditImageModel | string;
|
||||
scene_image_media_token?: string;
|
||||
image_media_tokens?: string[];
|
||||
prompt?: string;
|
||||
disable_system_prompt?: boolean;
|
||||
image_count?: number;
|
||||
aspect_ratio?: EnqueueContextualEditImageSize;
|
||||
image_quality?: EnqueueContextualEditImageQuality;
|
||||
}
|
||||
|
||||
export enum EnqueueContextualEditImageErrorType {
|
||||
ModelNotSpecified = "model_not_specified",
|
||||
NoProviderAvailable = "no_provider_available",
|
||||
BadRequest = "bad_request",
|
||||
ServerError = "server_error",
|
||||
TooManyConcurrentTasks = "too_many_concurrent_tasks",
|
||||
SoraLoginRequired = "sora_login_required",
|
||||
SoraUsernameNotYetCreated = "sora_username_not_yet_created",
|
||||
SoraIsHavingProblems = "sora_is_having_problems",
|
||||
}
|
||||
|
||||
export enum EnqueueContextualEditImageModel {
|
||||
GptImage1 = "gpt_image_1",
|
||||
FluxProKontextMax = "flux_pro_kontext_max",
|
||||
}
|
||||
|
||||
export enum EnqueueContextualEditImageSize {
|
||||
Auto = "auto",
|
||||
Square = "square",
|
||||
Wide = "wide",
|
||||
Tall = "tall",
|
||||
}
|
||||
|
||||
export enum EnqueueContextualEditImageQuality {
|
||||
Auto = "auto",
|
||||
High = "high",
|
||||
Medium = "medium",
|
||||
Low = "low",
|
||||
}
|
||||
|
||||
export interface EnqueueContextualEditImageError extends CommandResult {
|
||||
error_type: EnqueueContextualEditImageErrorType;
|
||||
error_message?: string;
|
||||
}
|
||||
|
||||
export interface EnqueueContextualEditImagePayload {
|
||||
}
|
||||
|
||||
export interface EnqueueContextualEditImageSuccess extends CommandResult {
|
||||
payload: EnqueueContextualEditImagePayload;
|
||||
}
|
||||
|
||||
export type EnqueueContextualEditImageResult = EnqueueContextualEditImageSuccess | EnqueueContextualEditImageError;
|
||||
|
||||
export const EnqueueContextualEditImage = async (request: EnqueueContextualEditImageRequest) : Promise<EnqueueContextualEditImageResult> => {
|
||||
let modelName = undefined;
|
||||
|
||||
if (!!request.model) {
|
||||
// NB: We can't use "instanceof" checks with Vite minification and class name mangling.
|
||||
if (typeof request.model === "string") {
|
||||
modelName = request.model;
|
||||
} else if (typeof request.model.tauriId === "string") {
|
||||
modelName = request.model.tauriId;
|
||||
}
|
||||
}
|
||||
|
||||
if (!modelName) {
|
||||
throw new Error("No model specified in request: " + JSON.stringify(request));
|
||||
}
|
||||
|
||||
let mutableRequest : RawEnqueueContextualEditImageRequest = {
|
||||
model: modelName,
|
||||
prompt: request.prompt,
|
||||
};
|
||||
|
||||
if (!!request.scene_image_media_token) {
|
||||
mutableRequest.scene_image_media_token = request.scene_image_media_token;
|
||||
}
|
||||
|
||||
if (!!request.image_media_tokens) {
|
||||
mutableRequest.image_media_tokens = request.image_media_tokens;
|
||||
}
|
||||
|
||||
if (!!request.aspect_ratio) {
|
||||
mutableRequest.aspect_ratio = request.aspect_ratio;
|
||||
}
|
||||
|
||||
if (!!request.image_count) {
|
||||
mutableRequest.image_count = request.image_count;
|
||||
}
|
||||
|
||||
if (!!request.image_quality) {
|
||||
mutableRequest.image_quality = request.image_quality;
|
||||
}
|
||||
|
||||
if (!!request.disable_system_prompt) {
|
||||
mutableRequest.disable_system_prompt = request.disable_system_prompt;
|
||||
}
|
||||
|
||||
const result = await invoke("enqueue_contextual_edit_image_command", {
|
||||
request: mutableRequest,
|
||||
});
|
||||
|
||||
return (result as EnqueueContextualEditImageResult);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
|
||||
export interface EnqueueImageBgRemovalRequest {
|
||||
image_media_token?: string;
|
||||
base64_image?: string;
|
||||
|
||||
// TODO: Actual enum.
|
||||
frontend_caller?: string;
|
||||
|
||||
// We'll use the node id here.
|
||||
frontend_subscriber_id?: string;
|
||||
}
|
||||
|
||||
interface RawEnqueueImageBgRemovalRequest {
|
||||
image_media_token?: string;
|
||||
base64_image?: string;
|
||||
frontend_caller?: string;
|
||||
frontend_subscriber_id?: string;
|
||||
}
|
||||
|
||||
export enum EnqueueImageBgRemovalErrorType {
|
||||
/// Caller didn't specify a model
|
||||
ModelNotSpecified = "model_not_specified",
|
||||
/// Generic server error
|
||||
ServerError = "server_error",
|
||||
/// No Fal API key available
|
||||
NeedsFalApiKey = "needs_fal_api_key",
|
||||
/// Fal had an API error
|
||||
FalError = "fal_error",
|
||||
}
|
||||
|
||||
export interface EnqueueImageBgRemovalError extends CommandResult {
|
||||
error_type: EnqueueImageBgRemovalErrorType;
|
||||
error_message?: string;
|
||||
}
|
||||
|
||||
export interface EnqueueImageBgRemovalPayload {
|
||||
}
|
||||
|
||||
export interface EnqueueImageBgRemovalSuccess extends CommandResult {
|
||||
payload: EnqueueImageBgRemovalPayload;
|
||||
}
|
||||
|
||||
export type EnqueueImageBgRemovalResult = EnqueueImageBgRemovalSuccess | EnqueueImageBgRemovalError;
|
||||
|
||||
export const EnqueueImageBgRemoval = async (request: EnqueueImageBgRemovalRequest) : Promise<EnqueueImageBgRemovalResult> => {
|
||||
let mutableRequest : RawEnqueueImageBgRemovalRequest = {};
|
||||
|
||||
if (!!request.image_media_token) {
|
||||
mutableRequest.image_media_token = request.image_media_token;
|
||||
}
|
||||
|
||||
if (!!request.base64_image) {
|
||||
mutableRequest.base64_image = request.base64_image;
|
||||
}
|
||||
|
||||
if (!!request.frontend_caller) {
|
||||
mutableRequest.frontend_caller = request.frontend_caller;
|
||||
}
|
||||
|
||||
if (!!request.frontend_subscriber_id) {
|
||||
mutableRequest.frontend_subscriber_id = request.frontend_subscriber_id;
|
||||
}
|
||||
|
||||
const result = await invoke("enqueue_image_bg_removal_command", {
|
||||
request: mutableRequest,
|
||||
});
|
||||
|
||||
return (result as EnqueueImageBgRemovalResult);
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
import { ImageModel, ModelInfo } from "@storyteller/model-list";
|
||||
|
||||
export interface EnqueueImageInpaintRequest {
|
||||
// The model to use.
|
||||
model?: ImageModel | ModelInfo | EnqueueImageInpaintModel;
|
||||
|
||||
// The image we're editing.
|
||||
image_media_token?: string;
|
||||
|
||||
// The mask to focus the edit (raw bytes).
|
||||
mask_image_raw_bytes?: Uint8Array;
|
||||
|
||||
// The user's image generation prompt.
|
||||
prompt?: string;
|
||||
|
||||
// Number of images to generate.
|
||||
image_count?: number;
|
||||
|
||||
// TODO: Actual enum.
|
||||
frontend_caller?: string;
|
||||
|
||||
// Optional frontend state to return later.
|
||||
frontend_subscriber_id?: string;
|
||||
}
|
||||
|
||||
|
||||
// Shape of request sent to Tauri
|
||||
// (We do some transformations from the public-facing request object.)
|
||||
interface RawEnqueueImageInpaintRequest {
|
||||
model?: EnqueueImageInpaintModel | string;
|
||||
image_media_token?: string;
|
||||
mask_image_raw_bytes?: Uint8Array;
|
||||
prompt?: string;
|
||||
image_count?: number;
|
||||
frontend_caller?: string;
|
||||
frontend_subscriber_id?: string;
|
||||
}
|
||||
|
||||
export enum EnqueueImageInpaintErrorType {
|
||||
ModelNotSpecified = "model_not_specified",
|
||||
NoProviderAvailable = "no_provider_available",
|
||||
BadRequest = "bad_request",
|
||||
ServerError = "server_error",
|
||||
TooManyConcurrentTasks = "too_many_concurrent_tasks",
|
||||
SoraLoginRequired = "sora_login_required",
|
||||
SoraUsernameNotYetCreated = "sora_username_not_yet_created",
|
||||
SoraIsHavingProblems = "sora_is_having_problems",
|
||||
}
|
||||
|
||||
export enum EnqueueImageInpaintModel {
|
||||
FluxPro1 = "flux_pro_1",
|
||||
FluxDevJuggernaut = "flux_dev_juggernaut",
|
||||
}
|
||||
|
||||
export interface EnqueueImageInpaintError extends CommandResult {
|
||||
error_type: EnqueueImageInpaintErrorType;
|
||||
error_message?: string;
|
||||
}
|
||||
|
||||
export interface EnqueueImageInpaintPayload {
|
||||
}
|
||||
|
||||
export interface EnqueueImageInpaintSuccess extends CommandResult {
|
||||
payload: EnqueueImageInpaintPayload;
|
||||
}
|
||||
|
||||
export type EnqueueImageInpaintResult = EnqueueImageInpaintSuccess | EnqueueImageInpaintError;
|
||||
|
||||
export const EnqueueImageInpaint = async (request: EnqueueImageInpaintRequest) : Promise<EnqueueImageInpaintResult> => {
|
||||
let modelName = undefined;
|
||||
|
||||
if (!!request.model) {
|
||||
if (typeof request.model === "string") {
|
||||
modelName = request.model;
|
||||
} else if ("tauriId" in request.model && typeof request.model.tauriId === "string") {
|
||||
modelName = request.model.tauriId;
|
||||
} else if ("tauri_id" in request.model && typeof request.model.tauri_id === "string") {
|
||||
modelName = request.model.tauri_id;
|
||||
}
|
||||
}
|
||||
|
||||
if (!modelName) {
|
||||
throw new Error("No model specified in request: " + JSON.stringify(request));
|
||||
}
|
||||
|
||||
let mutableRequest : RawEnqueueImageInpaintRequest = {
|
||||
model: modelName,
|
||||
prompt: request.prompt,
|
||||
};
|
||||
|
||||
if (!!request.image_media_token) {
|
||||
mutableRequest.image_media_token = request.image_media_token;
|
||||
}
|
||||
|
||||
if (!!request.mask_image_raw_bytes) {
|
||||
mutableRequest.mask_image_raw_bytes = request.mask_image_raw_bytes;
|
||||
}
|
||||
|
||||
if (!!request.image_count) {
|
||||
mutableRequest.image_count = request.image_count;
|
||||
}
|
||||
|
||||
if (!!request.frontend_caller) {
|
||||
mutableRequest.frontend_caller = request.frontend_caller;
|
||||
}
|
||||
|
||||
if (!!request.frontend_subscriber_id) {
|
||||
mutableRequest.frontend_subscriber_id = request.frontend_subscriber_id;
|
||||
}
|
||||
|
||||
const result = await invoke("enqueue_image_inpaint_command", {
|
||||
request: mutableRequest,
|
||||
});
|
||||
|
||||
return (result as EnqueueImageInpaintResult);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
|
||||
export enum EnqueueImageTo3dObjectErrorType {
|
||||
/// Caller didn't specify a model
|
||||
ModelNotSpecified = "model_not_specified",
|
||||
/// Generic server error
|
||||
ServerError = "server_error",
|
||||
/// No Fal API key available
|
||||
NeedsFalApiKey = "needs_fal_api_key",
|
||||
/// Fal had an API error
|
||||
FalError = "fal_error",
|
||||
/// Need tobe logged into Artcraft
|
||||
NeedsStorytellerCredentials = "needs_storyteller_credentials",
|
||||
}
|
||||
|
||||
export interface EnqueueImageTo3dObjectRequest {
|
||||
image_media_token?: string;
|
||||
model?: EnqueueImageTo3dObjectModel;
|
||||
}
|
||||
|
||||
export enum EnqueueImageTo3dObjectModel {
|
||||
Hunyuan3d2 = "hunyuan_3d_2",
|
||||
Hunyuan3d2_0 = "hunyuan_3d_2_0",
|
||||
Hunyuan3d2_1 = "hunyuan_3d_2_1",
|
||||
}
|
||||
|
||||
export interface EnqueueImageTo3dObjectError extends CommandResult {
|
||||
error_type: EnqueueImageTo3dObjectErrorType;
|
||||
error_message?: string;
|
||||
}
|
||||
|
||||
export interface EnqueueImageTo3dObjectPayload {
|
||||
}
|
||||
|
||||
export interface EnqueueImageTo3dObjectSuccess extends CommandResult {
|
||||
payload: EnqueueImageTo3dObjectPayload;
|
||||
}
|
||||
|
||||
export type EnqueueImageTo3dObjectResult = EnqueueImageTo3dObjectSuccess | EnqueueImageTo3dObjectError;
|
||||
|
||||
export const EnqueueImageTo3dObject = async (request: EnqueueImageTo3dObjectRequest) : Promise<EnqueueImageTo3dObjectResult> => {
|
||||
let result = await invoke("enqueue_image_to_3d_object_command", {
|
||||
request: {
|
||||
image_media_token: request.image_media_token,
|
||||
model: request.model,
|
||||
}
|
||||
});
|
||||
return (result as EnqueueImageTo3dObjectResult);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
import { Model } from "@storyteller/model-list";
|
||||
|
||||
export enum EnqueueImageToVideoErrorType {
|
||||
/// Caller didn't specify a model
|
||||
ModelNotSpecified = "model_not_specified",
|
||||
/// Generic server error
|
||||
ServerError = "server_error",
|
||||
/// No Fal API key available
|
||||
NeedsFalApiKey = "needs_fal_api_key",
|
||||
/// Fal had an API error
|
||||
FalError = "fal_error",
|
||||
}
|
||||
|
||||
export interface EnqueueImageToVideoRequest {
|
||||
// Required. The model to use.
|
||||
model?: Model;
|
||||
|
||||
// Required. Starting frame.
|
||||
image_media_token?: string;
|
||||
|
||||
// Optional. Ending frame.
|
||||
end_frame_image_media_token?: string;
|
||||
|
||||
// Optional. Text prompt to direct the video.
|
||||
prompt?: string;
|
||||
|
||||
// Optional frontend state to return later.
|
||||
frontend_caller?: string;
|
||||
|
||||
// Optional frontend state to return later.
|
||||
frontend_subscriber_id?: string;
|
||||
}
|
||||
|
||||
interface RawEnqueueImageToVideoRequest {
|
||||
model?: string;
|
||||
image_media_token?: string;
|
||||
end_frame_image_media_token?: string;
|
||||
prompt?: string;
|
||||
frontend_caller?: string;
|
||||
frontend_subscriber_id?: string;
|
||||
}
|
||||
|
||||
export interface EnqueueImageToVideoError extends CommandResult {
|
||||
error_type: EnqueueImageToVideoErrorType;
|
||||
error_message?: string;
|
||||
}
|
||||
|
||||
export interface EnqueueImageToVideoPayload {}
|
||||
|
||||
export interface EnqueueImageToVideoSuccess extends CommandResult {
|
||||
payload: EnqueueImageToVideoPayload;
|
||||
}
|
||||
|
||||
export type EnqueueImageToVideoResult =
|
||||
| EnqueueImageToVideoSuccess
|
||||
| EnqueueImageToVideoError;
|
||||
|
||||
export const EnqueueImageToVideo = async (
|
||||
request: EnqueueImageToVideoRequest
|
||||
): Promise<EnqueueImageToVideoResult> => {
|
||||
let mutableRequest: RawEnqueueImageToVideoRequest = {
|
||||
model: request.model?.tauriId,
|
||||
image_media_token: request.image_media_token,
|
||||
};
|
||||
|
||||
if (!!request.prompt) {
|
||||
mutableRequest.prompt = request.prompt;
|
||||
}
|
||||
|
||||
if (!!request.end_frame_image_media_token) {
|
||||
mutableRequest.end_frame_image_media_token =
|
||||
request.end_frame_image_media_token;
|
||||
}
|
||||
|
||||
if (!!request.frontend_caller) {
|
||||
mutableRequest.frontend_caller = request.frontend_caller;
|
||||
}
|
||||
|
||||
if (!!request.frontend_subscriber_id) {
|
||||
mutableRequest.frontend_subscriber_id = request.frontend_subscriber_id;
|
||||
}
|
||||
|
||||
const result = await invoke("enqueue_image_to_video_command", {
|
||||
request: mutableRequest,
|
||||
});
|
||||
|
||||
return result as EnqueueImageToVideoResult;
|
||||
};
|
||||
@@ -0,0 +1,131 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
import { Model } from "@storyteller/model-list";
|
||||
|
||||
export enum EnqueueTextToImageErrorType {
|
||||
/// Caller didn't specify a model
|
||||
ModelNotSpecified = "model_not_specified",
|
||||
/// Generic server error
|
||||
ServerError = "server_error",
|
||||
/// No Fal API key available
|
||||
NeedsFalApiKey = "needs_fal_api_key",
|
||||
/// Fal had an API error
|
||||
FalError = "fal_error",
|
||||
}
|
||||
|
||||
export interface EnqueueTextToImageRequest {
|
||||
// The model to use.
|
||||
model?: Model | EnqueueTextToImageModel;
|
||||
|
||||
// The text prompt.
|
||||
prompt?: string;
|
||||
|
||||
// The desired output aspect ratio.
|
||||
aspect_ratio?: EnqueueTextToImageSize;
|
||||
|
||||
// The number of images to generate.
|
||||
number_images?: number;
|
||||
|
||||
// Optional image-to-image prompts
|
||||
// These are not semantic buckets, but rather just "reference images",
|
||||
// and models do not have any further instruction about them. (ie. they
|
||||
// are not "style", "character", etc. references)
|
||||
image_media_tokens?: string[];
|
||||
|
||||
// Optional frontend state to return later.
|
||||
// TODO: Actual enum.
|
||||
frontend_caller?: string;
|
||||
|
||||
// Optional frontend state to return later.
|
||||
frontend_subscriber_id?: string;
|
||||
}
|
||||
|
||||
// Shape of request sent to Tauri
|
||||
// (We do some transformations from the public-facing request object.)
|
||||
interface EnqueueTextToImageRawRequest {
|
||||
prompt?: string;
|
||||
model?: EnqueueTextToImageModel | string; // TODO: Shouldn't allow string
|
||||
aspect_ratio?: EnqueueTextToImageSize;
|
||||
number_images?: number;
|
||||
image_media_tokens?: string[];
|
||||
frontend_caller?: string;
|
||||
frontend_subscriber_id?: string;
|
||||
}
|
||||
|
||||
export enum EnqueueTextToImageModel {
|
||||
FluxProUltra = "flux_pro_ultra",
|
||||
GptImage1 = "gpt_image_1",
|
||||
Recraft3 = "recraft_3",
|
||||
}
|
||||
|
||||
export enum EnqueueTextToImageSize {
|
||||
Auto = "auto",
|
||||
Square = "square",
|
||||
Wide = "wide",
|
||||
Tall = "tall",
|
||||
}
|
||||
|
||||
export interface EnqueueTextToImageError extends CommandResult {
|
||||
error_type: EnqueueTextToImageErrorType;
|
||||
error_message?: string;
|
||||
}
|
||||
|
||||
export interface EnqueueTextToImagePayload {
|
||||
media_token: string;
|
||||
cdn_url: string;
|
||||
base64_bytes: string;
|
||||
}
|
||||
|
||||
export interface EnqueueTextToImageSuccess extends CommandResult {
|
||||
payload: EnqueueTextToImagePayload;
|
||||
}
|
||||
|
||||
export type EnqueueTextToImageResult = EnqueueTextToImageSuccess | EnqueueTextToImageError;
|
||||
|
||||
export const EnqueueTextToImage = async (request: EnqueueTextToImageRequest) : Promise<EnqueueTextToImageResult> => {
|
||||
let modelName = undefined;
|
||||
|
||||
if (!!request.model) {
|
||||
// NB: We can't use "instanceof" checks with Vite minification and class name mangling.
|
||||
if (typeof request.model === "string") {
|
||||
modelName = request.model;
|
||||
} else if (typeof request.model.tauriId === "string") {
|
||||
modelName = request.model.tauriId;
|
||||
}
|
||||
}
|
||||
|
||||
if (!modelName) {
|
||||
throw new Error("No model specified in request: " + JSON.stringify(request));
|
||||
}
|
||||
|
||||
let mutableRequest : EnqueueTextToImageRawRequest = {
|
||||
model: modelName,
|
||||
prompt: request.prompt,
|
||||
};
|
||||
|
||||
if (!!request.aspect_ratio) {
|
||||
mutableRequest.aspect_ratio = request.aspect_ratio;
|
||||
}
|
||||
|
||||
if (!!request.number_images) {
|
||||
mutableRequest.number_images = request.number_images;
|
||||
}
|
||||
|
||||
if (!!request.image_media_tokens && request.image_media_tokens.length > 0) {
|
||||
mutableRequest.image_media_tokens = request.image_media_tokens;
|
||||
}
|
||||
|
||||
if (!!request.frontend_caller) {
|
||||
mutableRequest.frontend_caller = request.frontend_caller;
|
||||
}
|
||||
|
||||
if (!!request.frontend_subscriber_id) {
|
||||
mutableRequest.frontend_subscriber_id = request.frontend_subscriber_id;
|
||||
}
|
||||
|
||||
const result = await invoke("enqueue_text_to_image_command", {
|
||||
request: mutableRequest,
|
||||
});
|
||||
|
||||
return (result as EnqueueTextToImageResult);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
export enum BasicEventStatus {
|
||||
Success = "success",
|
||||
Failure = "failure",
|
||||
};
|
||||
|
||||
export interface BasicEventWrapper<T> {
|
||||
status: BasicEventStatus,
|
||||
data: T,
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
import { listen, UnlistenFn } from '@tauri-apps/api/event';
|
||||
import { BasicEventWrapper } from './BasicEventWrapper';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
const EVENT_NAME : string = 'canvas_bg_removed_event';
|
||||
|
||||
export interface CanvasBgRemovedEvent {
|
||||
media_token: string,
|
||||
image_cdn_url: string,
|
||||
maybe_frontend_subscriber_id?: string,
|
||||
maybe_frontend_subscriber_payload?: string,
|
||||
}
|
||||
|
||||
export const useCanvasBgRemovedEvent = (asyncCallback: (event: CanvasBgRemovedEvent) => Promise<void>) => {
|
||||
useEffect(() => {
|
||||
let isUnmounted = false;
|
||||
let unlisten: Promise<UnlistenFn>;
|
||||
|
||||
const setup = async () => {
|
||||
unlisten = listen<BasicEventWrapper<CanvasBgRemovedEvent>>(EVENT_NAME, async (wrappedEvent) => {
|
||||
await asyncCallback(wrappedEvent.payload.data);
|
||||
});
|
||||
|
||||
if (isUnmounted) {
|
||||
unlisten.then(f => f()); // Unsubscribe if unmounted early.
|
||||
}
|
||||
};
|
||||
|
||||
setup();
|
||||
|
||||
return () => {
|
||||
isUnmounted = true;
|
||||
unlisten.then(f => f());
|
||||
};
|
||||
|
||||
}, []);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
|
||||
export enum FalBackgroundRemovalErrorType {
|
||||
ServerError = "server_error",
|
||||
NeedsFalApiKey = "needs_fal_api_key",
|
||||
}
|
||||
|
||||
export interface FalBackgroundRemovalRequest {
|
||||
image_media_token?: string;
|
||||
base64_image?: string;
|
||||
}
|
||||
|
||||
export interface FalBackgroundRemovalError extends CommandResult {
|
||||
error_type: FalBackgroundRemovalErrorType;
|
||||
error_message?: string;
|
||||
}
|
||||
|
||||
export interface FalBackgroundRemovalPayload {
|
||||
media_token: string;
|
||||
cdn_url: string;
|
||||
base64_bytes: string;
|
||||
}
|
||||
|
||||
export interface FalBackgroundRemovalSuccess extends CommandResult {
|
||||
payload: FalBackgroundRemovalPayload;
|
||||
}
|
||||
|
||||
export type FalBackgroundRemovalResult = FalBackgroundRemovalSuccess | FalBackgroundRemovalError;
|
||||
|
||||
export const FalBackgroundRemoval = async (request: FalBackgroundRemovalRequest) : Promise<FalBackgroundRemovalResult> => {
|
||||
let result = await invoke("fal_background_removal_command", {
|
||||
request: {
|
||||
image_media_token: request.image_media_token,
|
||||
base64_image: request.base64_image,
|
||||
}
|
||||
});
|
||||
return (result as FalBackgroundRemovalResult);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
|
||||
export enum FalHunyuanImageTo3dErrorType {
|
||||
ServerError = "server_error",
|
||||
NeedsFalApiKey = "needs_fal_api_key",
|
||||
}
|
||||
|
||||
export interface FalHunyuanImageTo3dRequest {
|
||||
image_media_token?: string;
|
||||
base64_image?: string;
|
||||
}
|
||||
|
||||
export interface FalHunyuanImageTo3dError extends CommandResult {
|
||||
error_type: FalHunyuanImageTo3dErrorType;
|
||||
error_message?: string;
|
||||
}
|
||||
|
||||
export interface FalHunyuanImageTo3dPayload {
|
||||
media_token: string;
|
||||
cdn_url: string;
|
||||
base64_bytes: string;
|
||||
}
|
||||
|
||||
export interface FalHunyuanImageTo3dSuccess extends CommandResult {
|
||||
payload: FalHunyuanImageTo3dPayload;
|
||||
}
|
||||
|
||||
export type FalHunyuanImageTo3dResult = FalHunyuanImageTo3dSuccess | FalHunyuanImageTo3dError;
|
||||
|
||||
export const FalHunyuanImageTo3d = async (request: FalHunyuanImageTo3dRequest) : Promise<FalHunyuanImageTo3dResult> => {
|
||||
let result = await invoke("fal_hunyuan_image_to_3d_command", {
|
||||
request: {
|
||||
image_media_token: request.image_media_token,
|
||||
base64_image: request.base64_image,
|
||||
}
|
||||
});
|
||||
return (result as FalHunyuanImageTo3dResult);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
|
||||
export enum FalKlingImageToVideoErrorType {
|
||||
ServerError = "server_error",
|
||||
NeedsFalApiKey = "needs_fal_api_key",
|
||||
}
|
||||
|
||||
export interface FalKlingImageToVideoRequest {
|
||||
image_media_token?: string;
|
||||
base64_image?: string;
|
||||
}
|
||||
|
||||
export interface FalKlingImageToVideoError extends CommandResult {
|
||||
error_type: FalKlingImageToVideoErrorType;
|
||||
error_message?: string;
|
||||
}
|
||||
|
||||
export interface FalKlingImageToVideoPayload {
|
||||
media_token: string;
|
||||
cdn_url: string;
|
||||
base64_bytes: string;
|
||||
}
|
||||
|
||||
export interface FalKlingImageToVideoSuccess extends CommandResult {
|
||||
payload: FalKlingImageToVideoPayload;
|
||||
}
|
||||
|
||||
export type FalKlingImageToVideoResult = FalKlingImageToVideoSuccess | FalKlingImageToVideoError;
|
||||
|
||||
export const FalKlingImageToVideo = async (request: FalKlingImageToVideoRequest) : Promise<FalKlingImageToVideoResult> => {
|
||||
let result = await invoke("fal_kling_image_to_video_command", {
|
||||
request: {
|
||||
image_media_token: request.image_media_token,
|
||||
base64_image: request.base64_image,
|
||||
}
|
||||
});
|
||||
return (result as FalKlingImageToVideoResult);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
|
||||
export interface GetFalApiKeySuccessResult extends CommandResult {
|
||||
payload: {
|
||||
key: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type GetFalApiKeyResult = GetFalApiKeySuccessResult | CommandResult;
|
||||
|
||||
export const GetFalApiKey = async (): Promise<GetFalApiKeyResult> => {
|
||||
let result = await invoke("get_fal_api_key_command");
|
||||
return result as GetFalApiKeyResult;
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
|
||||
export const SetFalApiKey = async (key: string) : Promise<CommandResult> => {
|
||||
let result = await invoke("set_fal_api_key_command", {
|
||||
request: {
|
||||
key: key,
|
||||
}
|
||||
});
|
||||
return (result as CommandResult);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
|
||||
export interface MidjourneyGetCredentialInfoPayload {
|
||||
maybe_email?: string;
|
||||
can_clear_state: boolean;
|
||||
}
|
||||
|
||||
export interface MidjourneyGetCredentialInfoSuccess extends CommandResult {
|
||||
payload: MidjourneyGetCredentialInfoPayload;
|
||||
}
|
||||
|
||||
export const MidjourneyGetCredentialInfo = async (): Promise<MidjourneyGetCredentialInfoSuccess> => {
|
||||
const result = await invoke("midjourney_get_credential_info_command");
|
||||
return result as MidjourneyGetCredentialInfoSuccess;
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
|
||||
export interface GetOpenAIApiKeySuccessResult extends CommandResult {
|
||||
payload: {
|
||||
key: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type GetOpenAIApiKeyResult = GetOpenAIApiKeySuccessResult | CommandResult;
|
||||
|
||||
export const GetOpenAIApiKey = async (): Promise<GetOpenAIApiKeyResult> => {
|
||||
const result = await invoke("get_openai_api_key_command");
|
||||
return result as GetOpenAIApiKeyResult;
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
|
||||
export const SetOpenAIApiKey = async (key: string): Promise<CommandResult> => {
|
||||
const result = await invoke("set_openai_api_key_command", {
|
||||
request: {
|
||||
key: key,
|
||||
}
|
||||
});
|
||||
return result as CommandResult;
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
import { Provider } from "./Provider";
|
||||
|
||||
export interface GetProviderOrderSuccess extends CommandResult {
|
||||
payload: GetProviderOrderPayload;
|
||||
}
|
||||
|
||||
export interface GetProviderOrderPayload {
|
||||
providers: Provider[];
|
||||
}
|
||||
|
||||
// Returns the Success and Error variants directly.
|
||||
// Throws on Network/Tauri errors.
|
||||
export const GetProviderOrder = async () : Promise<GetProviderOrderSuccess> => {
|
||||
try {
|
||||
return await invoke("get_provider_order_command") as GetProviderOrderSuccess;
|
||||
} catch (error) {
|
||||
// NB: Endpoint should be infalliable
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
export enum Provider {
|
||||
ArtCraft = "artcraft",
|
||||
Fal = "fal",
|
||||
Sora = "sora",
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
import { Provider } from "./Provider";
|
||||
|
||||
export interface SetProviderOrderRequest {
|
||||
providers: Provider[];
|
||||
}
|
||||
|
||||
export const SetProviderOrder = async (request: SetProviderOrderRequest) : Promise<CommandResult> => {
|
||||
const result = await invoke("set_provider_order_command", {
|
||||
request: {
|
||||
providers: request.providers,
|
||||
}
|
||||
});
|
||||
|
||||
return (result as CommandResult);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
|
||||
export interface GetAppPreferencesResult {
|
||||
preferences: AppPreferencesPayload,
|
||||
}
|
||||
|
||||
export interface AppPreferencesPayload {
|
||||
// Preferred download directory
|
||||
preferred_download_directory: PreferredDownloadDirectory,
|
||||
|
||||
// Play sounds on events.
|
||||
play_sounds: boolean,
|
||||
|
||||
// Sound names to play.
|
||||
// These are keys, not filenames, and are defined by the frontend.
|
||||
enqueue_success_sound?: string,
|
||||
enqueue_failure_sound?: string,
|
||||
generation_success_sound?: string,
|
||||
generation_failure_sound?: string,
|
||||
generation_enqueue_sound?: string,
|
||||
}
|
||||
|
||||
export type PreferredDownloadDirectory = SystemDirectory | CustomDirectory;
|
||||
|
||||
export interface SystemDirectory {
|
||||
// If the directory is a system directory.
|
||||
system: string,
|
||||
}
|
||||
|
||||
export interface CustomDirectory {
|
||||
// If the directory is a custom user directory.
|
||||
custom: string,
|
||||
}
|
||||
|
||||
export const GetAppPreferences = async () : Promise<GetAppPreferencesResult> => {
|
||||
let result = await invoke("get_app_preferences_command");
|
||||
return (result as GetAppPreferencesResult);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { PreferredDownloadDirectory } from "./GetAppPreferences";
|
||||
|
||||
export interface UpdateAppPreferencesRequest {
|
||||
preference: PreferenceName,
|
||||
value: undefined | string | boolean | PreferredDownloadDirectory,
|
||||
}
|
||||
|
||||
export enum PreferenceName {
|
||||
PreferredDownloadDirectory = "preferred_download_directory",
|
||||
PlaySounds = "play_sounds",
|
||||
EnqueueSuccessSound = "enqueue_success_sound",
|
||||
EnqueueFailureSound = "enqueue_failure_sound",
|
||||
GenerationSuccessSound = "generation_success_sound",
|
||||
GenerationFailureSound = "generation_failure_sound",
|
||||
GenerationEnqueueSound = "generation_enqueue_sound",
|
||||
}
|
||||
|
||||
export interface UpdateAppPreferencesResult {
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export const UpdateAppPreferences = async (request: UpdateAppPreferencesRequest) : Promise<UpdateAppPreferencesResult> => {
|
||||
let result = await invoke("update_app_preferences_command", {
|
||||
request: {
|
||||
preference: request.preference,
|
||||
value: request.value,
|
||||
}
|
||||
});
|
||||
return (result as UpdateAppPreferencesResult);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
|
||||
export interface CheckSoraSessionResult {
|
||||
state: SoraSessionState;
|
||||
maybe_account_email?: string;
|
||||
}
|
||||
|
||||
export enum SoraSessionState {
|
||||
NotSetUp = "not_set_up",
|
||||
ExpiredOrError = "expired_or_error",
|
||||
Valid = "valid",
|
||||
}
|
||||
|
||||
export const CheckSoraSession = async (): Promise<CheckSoraSessionResult> => {
|
||||
const result = await invoke("check_sora_session_command");
|
||||
console.log(">>> sora result", result);
|
||||
return result as CheckSoraSessionResult;
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
|
||||
export const LogoutSoraSession = async (): Promise<void> => {
|
||||
return await invoke("sora_logout_command");
|
||||
};
|
||||
@@ -0,0 +1,65 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
|
||||
export interface SoraImageRemixRequest {
|
||||
// The media token of the visible screen snapshot
|
||||
snapshot_media_token: string,
|
||||
|
||||
// Whether to disable (our) system prompt.
|
||||
disable_system_prompt: boolean,
|
||||
|
||||
// The text prompt
|
||||
prompt: string,
|
||||
|
||||
// Additional images (media tokens) to use as reference.
|
||||
maybe_additional_images: string[],
|
||||
|
||||
// Typically "1"
|
||||
maybe_number_of_samples: number,
|
||||
|
||||
// The aspect ratio of the output image
|
||||
aspect_ratio?: SoraImageRemixAspectRatio,
|
||||
}
|
||||
|
||||
export enum SoraImageRemixAspectRatio {
|
||||
Square = "square",
|
||||
Wide = "wide",
|
||||
Tall = "tall",
|
||||
}
|
||||
|
||||
export interface SoraImageRemixSuccess extends CommandResult {
|
||||
// TODO: Status fields (they're not on the backend yet)
|
||||
}
|
||||
|
||||
export enum SoraImageRemixErrorType {
|
||||
ServerError = "server_error",
|
||||
TooManyConcurrentTasks = "too_many_concurrent_tasks",
|
||||
SoraIsHavingProblems = "sora_is_having_problems",
|
||||
SoraLoginRequired = "sora_login_required",
|
||||
SoraUsernameNotYetCreated = "sora_username_not_yet_created",
|
||||
}
|
||||
|
||||
export interface SoraImageRemixError extends CommandResult {
|
||||
error_type: SoraImageRemixErrorType;
|
||||
error_message?: string;
|
||||
}
|
||||
|
||||
export type SoraImageRemixResult = SoraImageRemixSuccess | SoraImageRemixError;
|
||||
|
||||
// Returns the Success and Error variants directly.
|
||||
// Throws on Network/Tauri errors.
|
||||
export const SoraImageRemix = async (request: SoraImageRemixRequest) : Promise<SoraImageRemixResult> => {
|
||||
try {
|
||||
return await invoke("sora_image_remix_command", {
|
||||
request: request,
|
||||
}) as SoraImageRemixResult;
|
||||
} catch (error) {
|
||||
let maybeTypedError = error as CommandResult;
|
||||
if ("status" in maybeTypedError) {
|
||||
return maybeTypedError
|
||||
} else {
|
||||
// Something else with Tauri, network, etc.
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { useEffect } from "react";
|
||||
import { listen } from "@tauri-apps/api/event";
|
||||
|
||||
type SoraLoginSuccessPayload = {
|
||||
// TODO
|
||||
};
|
||||
|
||||
export function useSoraLoginListener(
|
||||
onSuccess: (payload: SoraLoginSuccessPayload) => void
|
||||
) {
|
||||
useEffect(() => {
|
||||
let unlisten: () => void;
|
||||
|
||||
const setupListener = async () => {
|
||||
const stop = await listen<SoraLoginSuccessPayload>(
|
||||
"sora-login-success",
|
||||
(event) => {
|
||||
onSuccess(event.payload);
|
||||
}
|
||||
);
|
||||
unlisten = stop;
|
||||
};
|
||||
|
||||
setupListener();
|
||||
|
||||
return () => {
|
||||
if (unlisten) unlisten();
|
||||
};
|
||||
}, [onSuccess]);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { listen } from "@tauri-apps/api/event";
|
||||
|
||||
export function waitForSoraLogin(): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
let unlisten: () => void;
|
||||
listen("sora-login-success", () => {
|
||||
if (unlisten) unlisten();
|
||||
resolve();
|
||||
}).then((stop) => {
|
||||
unlisten = stop;
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../common/CommandStatus";
|
||||
|
||||
export interface GetAppInfoSuccess extends CommandResult {
|
||||
payload: GetAppInfoPayload;
|
||||
}
|
||||
|
||||
export interface GetAppInfoPayload {
|
||||
artcraft_version: string;
|
||||
build_timestamp: string;
|
||||
git_commit_id?: string | null;
|
||||
git_commit_short_id?: string | null;
|
||||
git_commit_timestamp?: string | null;
|
||||
storyteller_host?: string | null;
|
||||
os_platform?: string | null;
|
||||
os_version?: string | null;
|
||||
}
|
||||
|
||||
// Returns the Success and Error variants directly.
|
||||
// Throws on Network/Tauri errors.
|
||||
export const GetAppInfo = async () : Promise<GetAppInfoSuccess> => {
|
||||
try {
|
||||
return await invoke("get_app_info_command") as GetAppInfoSuccess;
|
||||
} catch (error) {
|
||||
// NB: Endpoint should be infalliable
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
|
||||
export const LoadWithoutCors = async (url: string) : Promise<ArrayBuffer> => {
|
||||
try {
|
||||
// Tauri Result<Success, Error> - success case.
|
||||
let result = await invoke("load_without_cors_command", { url });
|
||||
return result as ArrayBuffer;
|
||||
} catch (error) {
|
||||
// Tauri Result<Success, Error> - error case.
|
||||
console.error("LoadWithoutCors error", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user