mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
feat(automate): make the pipeline builder fully multi-modal (#335)
* feat(shared): add outputModality to Tool metadata for crossing tools * feat(shared): add modalityForExtension, toolInputModality, toolOutputModality * fix(pipeline): route finalize and parent jobs to the pipeline's modality pool * feat(automate): add ConvertAudioControls pipeline step (exemplar) * feat(automate): add video tool settings controls to pipelines * feat(automate): add audio tool settings controls to pipelines * feat(automate): add document tool settings controls to pipelines * feat(automate): add chart-maker settings control to pipelines * feat(automate): warn on modality-incompatible pipeline steps * feat(automate): add single-file download button for pipeline results * refactor(automate): modality-aware icons, nav handler rename, mobile size bar * test(pipeline): cover audio, document, file, and cross-modality chains * i18n(automate): translate the modality-warning tooltip * test(pipeline): gate media-pool routing assertion on ffmpeg availability
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { TOOLS } from "../../../packages/shared/src/constants.js";
|
||||
import {
|
||||
modalityForExtension,
|
||||
toolInputModality,
|
||||
toolOutputModality,
|
||||
} from "../../../packages/shared/src/modality.js";
|
||||
|
||||
const tool = (id: string) => {
|
||||
const t = TOOLS.find((x) => x.id === id);
|
||||
if (!t) throw new Error(`tool ${id} not found`);
|
||||
return t;
|
||||
};
|
||||
|
||||
describe("modalityForExtension", () => {
|
||||
it("maps extensions to their owning modality", () => {
|
||||
expect(modalityForExtension(".png")).toBe("image");
|
||||
expect(modalityForExtension(".mp4")).toBe("video");
|
||||
expect(modalityForExtension(".mp3")).toBe("audio");
|
||||
expect(modalityForExtension(".pdf")).toBe("document");
|
||||
expect(modalityForExtension(".csv")).toBe("file");
|
||||
});
|
||||
it("is case-insensitive and tolerates a missing dot", () => {
|
||||
expect(modalityForExtension("PNG")).toBe("image");
|
||||
expect(modalityForExtension(".JPG")).toBe("image");
|
||||
});
|
||||
it("returns null for unknown extensions", () => {
|
||||
expect(modalityForExtension(".xyz")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("toolOutputModality", () => {
|
||||
it("defaults to the tool's modality", () => {
|
||||
expect(toolOutputModality(tool("resize"))).toBe("image");
|
||||
});
|
||||
it("uses the override for crossing tools", () => {
|
||||
expect(toolOutputModality(tool("extract-audio"))).toBe("audio");
|
||||
expect(toolOutputModality(tool("chart-maker"))).toBe("image");
|
||||
});
|
||||
});
|
||||
|
||||
describe("toolInputModality", () => {
|
||||
it("returns the tool modality for normal tools", () => {
|
||||
expect(toolInputModality(tool("trim-video"))).toBe("video");
|
||||
expect(toolInputModality(tool("compress-pdf"))).toBe("document");
|
||||
});
|
||||
it("derives the real input modality from acceptedInputs", () => {
|
||||
expect(toolInputModality(tool("gif-to-video"))).toBe("image");
|
||||
expect(toolInputModality(tool("chart-maker"))).toBe("file");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user