Skip to content

Commit

Permalink
fix(gui): load remaining defaults from server params
Browse files Browse the repository at this point in the history
  • Loading branch information
ssube committed Jan 27, 2023
1 parent 9b37c17 commit 88e4f74
Show file tree
Hide file tree
Showing 4 changed files with 352 additions and 113 deletions.
36 changes: 36 additions & 0 deletions api/params.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
{
"version": "0.5.0",
"bottom": {
"default": 0,
"min": 0,
"max": 512,
"step": 8
},
"cfg": {
"default": 6,
"min": 1,
Expand All @@ -18,12 +24,26 @@
"max": 1,
"step": 0.1
},
"fillColor": {
"default": "#000000",
"keys": []
},
"filter": {
"default": "none",
"keys": []
},
"height": {
"default": 512,
"min": 64,
"max": 1024,
"step": 8
},
"left": {
"default": 0,
"min": 0,
"max": 512,
"step": 8
},
"model": {
"default": "stable-diffusion-onnx-v1-5",
"keys": []
Expand All @@ -32,6 +52,10 @@
"default": "",
"keys": []
},
"noise": {
"default": "histogram",
"keys": []
},
"outscale": {
"default": 1,
"min": 1,
Expand All @@ -46,6 +70,12 @@
"default": "an astronaut eating a hamburger",
"keys": []
},
"right": {
"default": 0,
"min": 0,
"max": 512,
"step": 8
},
"scale": {
"default": 1,
"min": 1,
Expand Down Expand Up @@ -74,6 +104,12 @@
"max": 1,
"step": 0.01
},
"top": {
"default": 0,
"min": 0,
"max": 512,
"step": 8
},
"width": {
"default": 512,
"min": 64,
Expand Down
165 changes: 141 additions & 24 deletions gui/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
/* eslint-disable max-lines */
import { doesExist } from '@apextoaster/js-utils';

import { ServerParams } from './config.js';

/**
* Shared parameters for anything using models, which is pretty much everything.
*/
export interface ModelParams {
/**
* Which ONNX model to use.
* The diffusion model to use.
*/
model: string;

/**
* Hardware accelerator or CPU mode.
* The hardware acceleration platform to use.
*/
platform: string;

/**
* The upscaling model to use.
*/
upscaling: string;

/**
* The correction model to use.
*/
correction: string;
}

/**
* Shared parameters for most of the image requests.
*/
export interface BaseImgParams {
scheduler: string;
prompt: string;
Expand All @@ -27,20 +41,25 @@ export interface BaseImgParams {
seed: number;
}

export interface Img2ImgParams extends BaseImgParams {
source: Blob;
strength: number;
}

export type Img2ImgResponse = Required<Omit<Img2ImgParams, 'file'>>;

/**
* Parameters for txt2img requests.
*/
export interface Txt2ImgParams extends BaseImgParams {
width?: number;
height?: number;
}

export type Txt2ImgResponse = Required<Txt2ImgParams>;
/**
* Parameters for img2img requests.
*/
export interface Img2ImgParams extends BaseImgParams {
source: Blob;
strength: number;
}

/**
* Parameters for inpaint requests.
*/
export interface InpaintParams extends BaseImgParams {
mask: Blob;
source: Blob;
Expand All @@ -51,6 +70,11 @@ export interface InpaintParams extends BaseImgParams {
fillColor: string;
}

/**
* Additional parameters for outpaint border.
*
* @todo should be nested under inpaint/outpaint params
*/
export interface OutpaintPixels {
enabled: boolean;

Expand All @@ -60,14 +84,27 @@ export interface OutpaintPixels {
bottom: number;
}

/**
* Parameters for outpaint requests.
*/
export type OutpaintParams = InpaintParams & OutpaintPixels;

/**
* Additional parameters for the inpaint brush.
*
* These are not currently sent to the server and only stored in state.
*
* @todo move to state
*/
export interface BrushParams {
color: number;
size: number;
strength: number;
}

/**
* Additional parameters for upscaling.
*/
export interface UpscaleParams {
enabled: boolean;

Expand All @@ -78,10 +115,16 @@ export interface UpscaleParams {
faceStrength: number;
}

/**
* Parameters for upscale requests.
*/
export interface UpscaleReqParams {
source: Blob;
}

/**
* General response for most image requests.
*/
export interface ImageResponse {
output: {
key: string;
Expand All @@ -94,61 +137,120 @@ export interface ImageResponse {
};
}

/**
* Status response from the ready endpoint.
*/
export interface ReadyResponse {
ready: boolean;
}

/**
* List of available models.
*/
export interface ModelsResponse {
diffusion: Array<string>;
correction: Array<string>;
upscaling: Array<string>;
}

export interface ApiClient {
/**
* List the available filter masks for inpaint.
*/
masks(): Promise<Array<string>>;

/**
* List the available models.
*/
models(): Promise<ModelsResponse>;

/**
* List the available noise sources for inpaint.
*/
noises(): Promise<Array<string>>;

/**
* Get the valid server parameters to validate image parameters.
*/
params(): Promise<ServerParams>;

/**
* Get the available hardware acceleration platforms.
*/
platforms(): Promise<Array<string>>;

/**
* List the available pipeline schedulers.
*/
schedulers(): Promise<Array<string>>;

img2img(model: ModelParams, params: Img2ImgParams, upscale?: UpscaleParams): Promise<ImageResponse>;
/**
* Start a txt2img pipeline.
*/
txt2img(model: ModelParams, params: Txt2ImgParams, upscale?: UpscaleParams): Promise<ImageResponse>;

/**
* Start an im2img pipeline.
*/
img2img(model: ModelParams, params: Img2ImgParams, upscale?: UpscaleParams): Promise<ImageResponse>;

/**
* Start an inpaint pipeline.
*/
inpaint(model: ModelParams, params: InpaintParams, upscale?: UpscaleParams): Promise<ImageResponse>;

/**
* Start an outpaint pipeline.
*/
outpaint(model: ModelParams, params: OutpaintParams, upscale?: UpscaleParams): Promise<ImageResponse>;

/**
* Start an upscale pipeline.
*/
upscale(model: ModelParams, params: UpscaleReqParams, upscale?: UpscaleParams): Promise<ImageResponse>;

/**
* Check whether some pipeline's output is ready yet.
*/
ready(params: ImageResponse): Promise<ReadyResponse>;
}

export const STATUS_SUCCESS = 200;

export function paramsFromConfig(defaults: ServerParams): Required<BaseImgParams> {
return {
cfg: defaults.cfg.default,
negativePrompt: defaults.negativePrompt.default,
prompt: defaults.prompt.default,
scheduler: defaults.scheduler.default,
steps: defaults.steps.default,
seed: defaults.seed.default,
};
}

/**
* Fixed precision for integer parameters.
*/
export const FIXED_INTEGER = 0;

/**
* Fixed precision for float parameters.
*
* The GUI limits the input steps based on the server parameters, but this does limit
* the maximum precision that can be sent back to the server, and may have to be
* increased in the future.
*/
export const FIXED_FLOAT = 2;
export const STATUS_SUCCESS = 200;

export function equalResponse(a: ImageResponse, b: ImageResponse): boolean {
return a.output === b.output;
}

/**
* Join URL path segments, which always use a forward slash per https://www.rfc-editor.org/rfc/rfc1738
*/
export function joinPath(...parts: Array<string>): string {
return parts.join('/');
}

/**
* Build the URL to an API endpoint, given the API root and a list of segments.
*/
export function makeApiUrl(root: string, ...path: Array<string>) {
return new URL(joinPath('api', ...path), root);
}

/**
* Build the URL for an image request, including all of the base image parameters.
*/
export function makeImageURL(root: string, type: string, params: BaseImgParams): URL {
const url = makeApiUrl(root, type);
url.searchParams.append('cfg', params.cfg.toFixed(FIXED_FLOAT));
Expand All @@ -172,13 +274,19 @@ export function makeImageURL(root: string, type: string, params: BaseImgParams):
return url;
}

/**
* Append the model parameters to an existing URL.
*/
export function appendModelToURL(url: URL, params: ModelParams) {
url.searchParams.append('model', params.model);
url.searchParams.append('platform', params.platform);
url.searchParams.append('upscaling', params.upscaling);
url.searchParams.append('correction', params.correction);
}

/**
* Append the upscale parameters to an existing URL.
*/
export function appendUpscaleToURL(url: URL, upscale: UpscaleParams) {
if (upscale.enabled) {
url.searchParams.append('denoise', upscale.denoise.toFixed(FIXED_FLOAT));
Expand All @@ -189,6 +297,9 @@ export function appendUpscaleToURL(url: URL, upscale: UpscaleParams) {
}
}

/**
* Make an API client using the given API root and fetch client.
*/
export function makeClient(root: string, f = fetch): ApiClient {
let pending: Promise<ImageResponse> | undefined;

Expand Down Expand Up @@ -388,6 +499,12 @@ export function makeClient(root: string, f = fetch): ApiClient {
};
}

/**
* Parse a successful API response into the full image response record.
*
* The server sends over the output key, and the client is in the best position to turn
* that into a full URL, since it already knows the root URL of the server.
*/
export async function parseApiResponse(root: string, res: Response): Promise<ImageResponse> {
type LimitedResponse = Omit<ImageResponse, 'output'> & { output: string };

Expand Down
Loading

0 comments on commit 88e4f74

Please sign in to comment.