evOo-local/packages/adapters/src/studio-specialist.test.ts
Claude 5e0b09d9c1
feat(media): transcription input, chunked transcripts and the Studio trigger
Groundwork for the transcribe operation and for creating Studio when it is
first needed.

- Contracts: TranscribeInputSchema (artifact id, optional language code).
- transcribeChunks uploads audio chunks in order and stitches them into one
  transcript on the original timeline; transcriptionChunkSeconds sizes
  16 kHz mono WAV chunks below the server's upload limit; transcriptSummary
  hands the bot the transcript, cut at a word.
- ensureStudioWhenMediaConfigured creates Studio once a media server
  (generation or transcription) is configured. Local edits alone do not
  count, because ffmpeg and image tools are present on most installs and a
  specialist nobody asked for would appear for everyone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u
2026-10-03 13:35:21 +00:00

58 lines
2.0 KiB
TypeScript

import type { MediaCapabilities } from "@rakazo/adapter-kit";
import type { PrismaClient } from "@rakazo/db";
import { beforeEach, describe, expect, it, vi } from "vitest";
const ensureStudioBot = vi.fn();
vi.mock("@rakazo/db", () => ({
ensureStudioBot: (...args: unknown[]) => ensureStudioBot(...args),
}));
import { ensureStudioWhenMediaConfigured, mediaBackendsConfigured } from "./studio-specialist.js";
const none: MediaCapabilities = {
generate_image: false,
generate_video: false,
edit_image: false,
edit_video: false,
export_video: false,
transcribe: false,
};
const prisma = {} as PrismaClient;
const run = { userId: "user-1", spaceId: "space-1" };
describe("Studio specialist", () => {
beforeEach(() => {
ensureStudioBot.mockReset();
});
it("counts only media servers, not local edits, as media being set up", () => {
expect(mediaBackendsConfigured({ ...none, edit_image: true, edit_video: true })).toBe(false);
expect(mediaBackendsConfigured({ ...none, transcribe: true })).toBe(true);
expect(mediaBackendsConfigured({ ...none, generate_image: true })).toBe(true);
});
it("creates Studio once a media server is configured", async () => {
await ensureStudioWhenMediaConfigured(
{ prisma, media: { capabilities: async () => ({ ...none, edit_video: true }) } },
run,
);
await ensureStudioWhenMediaConfigured({ prisma }, run);
expect(ensureStudioBot).not.toHaveBeenCalled();
await ensureStudioWhenMediaConfigured(
{ prisma, media: { capabilities: async () => ({ ...none, transcribe: true }) } },
run,
);
expect(ensureStudioBot).toHaveBeenCalledWith(prisma, "user-1");
});
it("never fails the run", async () => {
ensureStudioBot.mockRejectedValue(new Error("database unavailable"));
await expect(
ensureStudioWhenMediaConfigured(
{ prisma, media: { capabilities: async () => ({ ...none, generate_video: true }) } },
run,
),
).resolves.toBeUndefined();
});
});