mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
feat: make AI tools pipeline-compatible and add search to tool picker
Register remove-background, upscale, and blur-faces in the pipeline tool registry via registerToolProcessFn(). These tools keep their custom HTTP routes (with progress callbacks) for direct use, but now also provide a simple process function for pipeline/batch execution. Add a search bar to the pipeline tool picker so users can quickly find tools by name or description. Uses the existing SearchBar component and the same filtering pattern as the main tool panel. Update tests to reflect that these 3 AI tools are now pipeline- compatible (moved from excluded to included assertions).
This commit is contained in:
@@ -49,13 +49,21 @@ export function getToolConfig(toolId: string): AnyToolRouteConfig | undefined {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the IDs of all tools registered via createToolRoute().
|
||||
* These are the tools that can be used in pipelines and batch processing.
|
||||
* Return the IDs of all tools in the pipeline/batch registry.
|
||||
*/
|
||||
export function getRegisteredToolIds(): string[] {
|
||||
return [...toolRegistry.keys()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a tool's process function in the pipeline/batch registry
|
||||
* without creating an HTTP route. Use this for tools that have their
|
||||
* own custom HTTP route but should still be usable in pipelines.
|
||||
*/
|
||||
export function registerToolProcessFn(config: AnyToolRouteConfig): void {
|
||||
toolRegistry.set(config.toolId, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory that registers a POST /api/v1/tools/:toolId route.
|
||||
*
|
||||
|
||||
@@ -3,10 +3,12 @@ import { writeFile } from "node:fs/promises";
|
||||
import { basename, join } from "node:path";
|
||||
import { blurFaces } from "@stirling-image/ai";
|
||||
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
||||
import { z } from "zod";
|
||||
import { autoOrient } from "../../lib/auto-orient.js";
|
||||
import { validateImageBuffer } from "../../lib/file-validation.js";
|
||||
import { createWorkspace } from "../../lib/workspace.js";
|
||||
import { updateSingleFileProgress } from "../progress.js";
|
||||
import { registerToolProcessFn } from "../tool-factory.js";
|
||||
|
||||
/**
|
||||
* Face detection and blurring route.
|
||||
@@ -115,4 +117,26 @@ export function registerBlurFaces(app: FastifyInstance) {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Register in the pipeline/batch registry so this tool can be used
|
||||
// as a step in automation pipelines (without progress callbacks).
|
||||
registerToolProcessFn({
|
||||
toolId: "blur-faces",
|
||||
settingsSchema: z.object({
|
||||
blurRadius: z.number().min(1).max(100).default(30),
|
||||
sensitivity: z.number().min(0).max(1).default(0.5),
|
||||
}),
|
||||
process: async (inputBuffer, settings, filename) => {
|
||||
const s = settings as { blurRadius?: number; sensitivity?: number };
|
||||
const orientedBuffer = await autoOrient(inputBuffer);
|
||||
const jobId = randomUUID();
|
||||
const workspacePath = await createWorkspace(jobId);
|
||||
const result = await blurFaces(orientedBuffer, join(workspacePath, "output"), {
|
||||
blurRadius: s.blurRadius ?? 30,
|
||||
sensitivity: s.sensitivity ?? 0.5,
|
||||
});
|
||||
const outputFilename = `${filename.replace(/\.[^.]+$/, "")}_blurred.png`;
|
||||
return { buffer: result.buffer, filename: outputFilename, contentType: "image/png" };
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,9 +3,11 @@ import { writeFile } from "node:fs/promises";
|
||||
import { basename, join } from "node:path";
|
||||
import { removeBackground } from "@stirling-image/ai";
|
||||
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
||||
import { z } from "zod";
|
||||
import { validateImageBuffer } from "../../lib/file-validation.js";
|
||||
import { createWorkspace } from "../../lib/workspace.js";
|
||||
import { updateSingleFileProgress } from "../progress.js";
|
||||
import { registerToolProcessFn } from "../tool-factory.js";
|
||||
|
||||
/**
|
||||
* AI background removal route.
|
||||
@@ -108,4 +110,25 @@ export function registerRemoveBackground(app: FastifyInstance) {
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Register in the pipeline/batch registry so this tool can be used
|
||||
// as a step in automation pipelines (without progress callbacks).
|
||||
registerToolProcessFn({
|
||||
toolId: "remove-background",
|
||||
settingsSchema: z.object({
|
||||
model: z.string().optional(),
|
||||
backgroundColor: z.string().optional(),
|
||||
}),
|
||||
process: async (inputBuffer, settings, filename) => {
|
||||
const s = settings as { model?: string; backgroundColor?: string };
|
||||
const jobId = randomUUID();
|
||||
const workspacePath = await createWorkspace(jobId);
|
||||
const resultBuffer = await removeBackground(inputBuffer, join(workspacePath, "output"), {
|
||||
model: s.model,
|
||||
backgroundColor: s.backgroundColor,
|
||||
});
|
||||
const outputFilename = `${filename.replace(/\.[^.]+$/, "")}_nobg.png`;
|
||||
return { buffer: resultBuffer, filename: outputFilename, contentType: "image/png" };
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,10 +3,12 @@ import { writeFile } from "node:fs/promises";
|
||||
import { basename, join } from "node:path";
|
||||
import { upscale } from "@stirling-image/ai";
|
||||
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
||||
import { z } from "zod";
|
||||
import { autoOrient } from "../../lib/auto-orient.js";
|
||||
import { validateImageBuffer } from "../../lib/file-validation.js";
|
||||
import { createWorkspace } from "../../lib/workspace.js";
|
||||
import { updateSingleFileProgress } from "../progress.js";
|
||||
import { registerToolProcessFn } from "../tool-factory.js";
|
||||
|
||||
/**
|
||||
* AI image upscaling route.
|
||||
@@ -114,4 +116,22 @@ export function registerUpscale(app: FastifyInstance) {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Register in the pipeline/batch registry so this tool can be used
|
||||
// as a step in automation pipelines (without progress callbacks).
|
||||
registerToolProcessFn({
|
||||
toolId: "upscale",
|
||||
settingsSchema: z.object({
|
||||
scale: z.union([z.number(), z.string()]).transform(Number).default(2),
|
||||
}),
|
||||
process: async (inputBuffer, settings, filename) => {
|
||||
const scale = Number((settings as { scale?: number }).scale) || 2;
|
||||
const orientedBuffer = await autoOrient(inputBuffer);
|
||||
const jobId = randomUUID();
|
||||
const workspacePath = await createWorkspace(jobId);
|
||||
const result = await upscale(orientedBuffer, join(workspacePath, "output"), { scale });
|
||||
const outputFilename = `${filename.replace(/\.[^.]+$/, "")}_${scale}x.png`;
|
||||
return { buffer: result.buffer, filename: outputFilename, contentType: "image/png" };
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user