diff --git a/packages/kbot/dist-in/commands/transcribe.d.ts b/packages/kbot/dist-in/commands/transcribe.d.ts index 3d47eef7..be85d671 100644 --- a/packages/kbot/dist-in/commands/transcribe.d.ts +++ b/packages/kbot/dist-in/commands/transcribe.d.ts @@ -1,3 +1,4 @@ import { IKBotTask } from '@polymech/ai-tools'; +export declare const default_sort: (files: string[]) => string[]; export declare const TranscribeOptionsSchema: () => any; export declare const transcribeCommand: (opts: IKBotTask) => Promise; diff --git a/packages/kbot/dist-in/commands/transcribe.js b/packages/kbot/dist-in/commands/transcribe.js index 728e0bc1..d843ce05 100644 --- a/packages/kbot/dist-in/commands/transcribe.js +++ b/packages/kbot/dist-in/commands/transcribe.js @@ -1,14 +1,32 @@ import * as path from 'node:path'; +import * as fs from 'node:fs'; import { isString, isArray } from '@polymech/core/primitives'; +import pMap from 'p-map'; import { hasMagic } from 'glob'; import { sync as exists } from '@polymech/fs/exists'; import { forward_slash, resolve, pathInfoEx } from '@polymech/commons'; import { OptionsSchema } from '../zod_schema.js'; import { transcribe } from '../lib/transcribe.js'; import { isWebUrl } from '../glob.js'; -import { default_sort } from './run.js'; import { getLogger } from '../index.js'; import { variables } from '../variables.js'; +export const default_sort = (files) => { + const getSortableParts = (filename) => { + const baseName = path.parse(filename).name; + const match = baseName.match(/^(\d+)_?(.*)$/); // Match leading numbers + const numPart = match ? parseInt(match[1], 10) : NaN; + const textPart = match ? match[2] : baseName; // Extract text part + return { numPart, textPart }; + }; + return files.sort((a, b) => { + const { numPart: aNum, textPart: aText } = getSortableParts(a); + const { numPart: bNum, textPart: bText } = getSortableParts(b); + if (!isNaN(aNum) && !isNaN(bNum)) { + return aNum - bNum || aText.localeCompare(bText, undefined, { numeric: true, sensitivity: 'base' }); + } + return aText.localeCompare(bText, undefined, { numeric: true, sensitivity: 'base' }); + }); +}; export const TranscribeOptionsSchema = () => { return OptionsSchema().pick({ include: true, @@ -82,7 +100,7 @@ export const transcribeCommand = async (opts) => { const info = pathInfoEx(forward_slash(path.resolve(resolve(includePath))), false, { absolute: true, }); - files.push(...default_sort(info.FILES)); + files.push(...info.FILES); } else if (exists(includePath)) { files.push(includePath); @@ -92,8 +110,9 @@ export const transcribeCommand = async (opts) => { opts.logger.warn(`No files found for --include patterns: ${opts.include.join(', ')}`); return; } + files = default_sort(files); opts.logger.info(`Found ${files.length} files to transcribe.`); - for (const file of files) { + const mapper = async (file) => { const fileInfo = path.parse(file); const CWD = process.cwd(); const current_variables = { @@ -110,15 +129,32 @@ export const transcribeCommand = async (opts) => { include: [file], variables: current_variables }; - if (!itemOpts.dst) { - itemOpts.dst = '${SRC_DIR}/${SRC_NAME}.md'; - } - itemOpts.dst = path.resolve(resolve(itemOpts.dst, itemOpts.alt, itemOpts.variables)); opts.logger.info(`Transcribing ${file}...`); - if (itemOpts.dst) { - opts.logger.info(`Output will be saved to ${itemOpts.dst}`); + const transcribedText = await transcribe(itemOpts); + return { transcribedText, itemOpts }; + }; + const results = await pMap(files, mapper, { concurrency: 1 }); + let resolvedDstPath; + if (opts.dst) { + resolvedDstPath = path.resolve(resolve(opts.dst, opts.alt, opts.variables)); + if (fs.existsSync(resolvedDstPath)) { + fs.unlinkSync(resolvedDstPath); + } + const allText = results.map(r => r.transcribedText).filter(Boolean).join('\n\n'); + if (allText) { + fs.writeFileSync(resolvedDstPath, allText + '\n'); + opts.logger.info(`Wrote all transcriptions to ${resolvedDstPath}`); + } + } + else { + for (const { transcribedText, itemOpts } of results) { + if (transcribedText) { + const defaultDstTemplate = '${SRC_DIR}/${SRC_NAME}.md'; + const defaultDstPath = path.resolve(resolve(defaultDstTemplate, itemOpts.alt, itemOpts.variables)); + fs.writeFileSync(defaultDstPath, transcribedText); + opts.logger.info(`Output will be saved to ${defaultDstPath}`); + } } - await transcribe(itemOpts); } }; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNjcmliZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy90cmFuc2NyaWJlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFBO0FBQ2pDLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE1BQU0sMkJBQTJCLENBQUE7QUFDN0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLE1BQU0sQ0FBQTtBQUMvQixPQUFPLEVBQUUsSUFBSSxJQUFJLE1BQU0sRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBQ3BELE9BQU8sRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBR3RFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQTtBQUNoRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUE7QUFDakQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUNyQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sVUFBVSxDQUFBO0FBQ3ZDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFDdkMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlCQUFpQixDQUFBO0FBRTNDLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLEdBQUcsRUFBRTtJQUN4QyxPQUFPLGFBQWEsRUFBRSxDQUFDLElBQUksQ0FBQztRQUN4QixPQUFPLEVBQUUsSUFBSTtRQUNiLEdBQUcsRUFBRSxJQUFJO1FBQ1QsT0FBTyxFQUFFLElBQUk7UUFDYixLQUFLLEVBQUUsSUFBSTtRQUNYLE1BQU0sRUFBRSxJQUFJO1FBQ1osUUFBUSxFQUFFLElBQUk7UUFDZCxNQUFNLEVBQUUsSUFBSTtRQUNaLE9BQU8sRUFBRSxJQUFJO1FBQ2IsR0FBRyxFQUFFLElBQUk7UUFDVCxTQUFTLEVBQUUsSUFBSTtR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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNjcmliZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy90cmFuc2NyaWJlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFBO0FBQ2pDLE9BQU8sS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQzdCLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE1BQU0sMkJBQTJCLENBQUE7QUFDN0QsT0FBTyxJQUFJLE1BQU0sT0FBTyxDQUFBO0FBQ3hCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxNQUFNLENBQUE7QUFDL0IsT0FBTyxFQUFFLElBQUksSUFBSSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUd0RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFDaEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFBO0FBQ2pELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFFckMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUN2QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFFM0MsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLENBQUMsS0FBZSxFQUFZLEVBQUU7SUFDdEQsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLFFBQWdCLEVBQUUsRUFBRTtRQUMxQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUMzQyxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsd0JBQXdCO1FBQ3ZFLE1BQU0sT0FBTyxHQUFHLEtBQUss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 \ No newline at end of file diff --git a/packages/kbot/dist-in/lib/transcribe.d.ts b/packages/kbot/dist-in/lib/transcribe.d.ts index 219cbf4a..3586166b 100644 --- a/packages/kbot/dist-in/lib/transcribe.d.ts +++ b/packages/kbot/dist-in/lib/transcribe.d.ts @@ -1,2 +1,2 @@ import { IKBotTask } from '@polymech/ai-tools'; -export declare const transcribe: (options: IKBotTask) => Promise; +export declare const transcribe: (options: IKBotTask) => Promise; diff --git a/packages/kbot/dist-in/lib/transcribe.js b/packages/kbot/dist-in/lib/transcribe.js index 2be42c22..a4def435 100644 --- a/packages/kbot/dist-in/lib/transcribe.js +++ b/packages/kbot/dist-in/lib/transcribe.js @@ -1,7 +1,6 @@ import * as fs from 'fs'; import { toFile } from "openai"; import { sync as exists } from '@polymech/fs/exists'; -import { sync as write } from '@polymech/fs/write'; import { createClient } from '../client.js'; const createBuffer = (path) => { try { @@ -17,21 +16,21 @@ export const transcribe = async (options) => { const client = createClient(options); if (!client) { options.logger.error('Failed to create client'); - return; + return ''; } if (!options.include || options.include.length === 0) { options.logger.error('No source file provided via --include'); - return; + return ''; } const sourceFile = options.include[0]; if (!exists(sourceFile)) { options.logger.error('Source file does not exist', sourceFile); - return; + return ''; } const file = await toFile(createBuffer(sourceFile), 'audio.mp3', { type: 'audio/mpeg' }); if (!file) { options.logger.error('Error converting source to file'); - return; + return ''; } const completion = await client.audio.transcriptions.create({ model: 'whisper-1', @@ -40,16 +39,9 @@ export const transcribe = async (options) => { }); if (!completion) { options.logger.error('OpenAI response is empty'); - return; + return ''; } const text_content = completion.text || ''; - if (options.dst) { - write(options.dst, text_content); - } - else { - process.stdout.write(text_content); - } - // options.logger.debug('OpenAI Transcribe response:', completion) - return completion; + return text_content; }; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNjcmliZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvdHJhbnNjcmliZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQTtBQUN4QixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sUUFBUSxDQUFBO0FBQy9CLE9BQU8sRUFBRSxJQUFJLElBQUksTUFBTSxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDcEQsT0FBTyxFQUFFLElBQUksSUFBSSxLQUFLLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUVsRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBRTNDLE1BQU0sWUFBWSxHQUFHLENBQUMsSUFBWSxFQUFpQixFQUFFO0lBQ2pELElBQUksQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDcEMsT0FBTyxNQUFNLENBQUM7SUFDbEIsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDYixPQUFPLENBQUMsS0FBSyxDQUFDLHdCQUF3QixFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQy9DLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7QUFDTCxDQUFDLENBQUE7QUFFRCxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsS0FBSyxFQUFFLE9BQWtCLEVBQUUsRUFBRTtJQUNuRCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDcEMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1YsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQTtRQUMvQyxPQUFNO0lBQ1YsQ0FBQztJQUVELElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ25ELE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHVDQUF1QyxDQUFDLENBQUE7UUFDN0QsT0FBTztJQUNYLENBQUM7SUFFRCxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRXRDLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztRQUN0QixPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyw0QkFBNEIsRUFBRSxVQUFVLENBQUMsQ0FBQTtRQUM5RCxPQUFPO0lBQ1gsQ0FBQztJQUVELE1BQU0sSUFBSSxHQUFHLE1BQU0sTUFBTSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsRUFBRSxXQUFXLEVBQUUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztJQUN6RixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDUixPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFBO1FBQ3ZELE9BQU87SUFDWCxDQUFDO0lBRUQsTUFBTSxVQUFVLEdBQVEsTUFBTSxNQUFNLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUM7UUFDN0QsS0FBSyxFQUFFLFdBQVc7UUFDbEIsSUFBSSxFQUFFLElBQUk7UUFDVixlQUFlLEVBQUcsT0FBZSxDQUFDLGVBQWUsSUFBSSxjQUFjO0tBQ3RFLENBQUMsQ0FBQTtJQUVGLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNkLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUE7UUFDaEQsT0FBTztJQUNYLENBQUM7SUFFRCxNQUFNLFlBQVksR0FBRyxVQUFVLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQztJQUUzQyxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNkLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLFlBQVksQ0FBQyxDQUFBO0lBQ3BDLENBQUM7U0FBTSxDQUFDO1FBQ0osT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUE7SUFDdEMsQ0FBQztJQUVELGtFQUFrRTtJQUNsRSxPQUFPLFVBQVUsQ0FBQTtBQUNyQixDQUFDLENBQUEifQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNjcmliZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvdHJhbnNjcmliZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQTtBQUN4QixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sUUFBUSxDQUFBO0FBQy9CLE9BQU8sRUFBRSxJQUFJLElBQUksTUFBTSxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFHcEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGNBQWMsQ0FBQTtBQUUzQyxNQUFNLFlBQVksR0FBRyxDQUFDLElBQVksRUFBaUIsRUFBRTtJQUNqRCxJQUFJLENBQUM7UUFDRCxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ3BDLE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2IsT0FBTyxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMvQyxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0FBQ0wsQ0FBQyxDQUFBO0FBRUQsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLEtBQUssRUFBRSxPQUFrQixFQUFtQixFQUFFO0lBQ3BFLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUNwQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDVixPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFBO1FBQy9DLE9BQU8sRUFBRSxDQUFBO0lBQ2IsQ0FBQztJQUVELElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ25ELE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHVDQUF1QyxDQUFDLENBQUE7UUFDN0QsT0FBTyxFQUFFLENBQUM7SUFDZCxDQUFDO0lBRUQsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUV0QyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7UUFDdEIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsNEJBQTRCLEVBQUUsVUFBVSxDQUFDLENBQUE7UUFDOUQsT0FBTyxFQUFFLENBQUM7SUFDZCxDQUFDO0lBRUQsTUFBTSxJQUFJLEdBQUcsTUFBTSxNQUFNLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxFQUFFLFdBQVcsRUFBRSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDO0lBQ3pGLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNSLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxDQUFDLENBQUE7UUFDdkQsT0FBTyxFQUFFLENBQUM7SUFDZCxDQUFDO0lBRUQsTUFBTSxVQUFVLEdBQVEsTUFBTSxNQUFNLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUM7UUFDN0QsS0FBSyxFQUFFLFdBQVc7UUFDbEIsSUFBSSxFQUFFLElBQUk7UUFDVixlQUFlLEVBQUcsT0FBZSxDQUFDLGVBQWUsSUFBSSxjQUFjO0tBQ3RFLENBQUMsQ0FBQTtJQUVGLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNkLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUE7UUFDaEQsT0FBTyxFQUFFLENBQUM7SUFDZCxDQUFDO0lBRUQsTUFBTSxZQUFZLEdBQUcsVUFBVSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUE7SUFDMUMsT0FBTyxZQUFZLENBQUE7QUFDdkIsQ0FBQyxDQUFBIn0= \ No newline at end of file diff --git a/packages/kbot/dist/win-64/kbot.exe b/packages/kbot/dist/win-64/kbot.exe new file mode 100644 index 00000000..ff199e67 Binary files /dev/null and b/packages/kbot/dist/win-64/kbot.exe differ diff --git a/packages/kbot/src/commands/transcribe.ts b/packages/kbot/src/commands/transcribe.ts index 0dd9aa6c..f6c62f79 100644 --- a/packages/kbot/src/commands/transcribe.ts +++ b/packages/kbot/src/commands/transcribe.ts @@ -1,5 +1,7 @@ import * as path from 'node:path' +import * as fs from 'node:fs' import { isString, isArray } from '@polymech/core/primitives' +import pMap from 'p-map' import { hasMagic } from 'glob' import { sync as exists } from '@polymech/fs/exists' import { forward_slash, resolve, pathInfoEx } from '@polymech/commons' @@ -8,10 +10,29 @@ import { IKBotTask } from '@polymech/ai-tools' import { OptionsSchema } from '../zod_schema.js' import { transcribe } from '../lib/transcribe.js' import { isWebUrl } from '../glob.js' -import { default_sort } from './run.js' + import { getLogger } from '../index.js' import { variables } from '../variables.js' +export const default_sort = (files: string[]): string[] => { + const getSortableParts = (filename: string) => { + const baseName = path.parse(filename).name; + const match = baseName.match(/^(\d+)_?(.*)$/); // Match leading numbers + const numPart = match ? parseInt(match[1], 10) : NaN; + const textPart = match ? match[2] : baseName; // Extract text part + + return { numPart, textPart }; + } + return files.sort((a, b) => { + const { numPart: aNum, textPart: aText } = getSortableParts(a) + const { numPart: bNum, textPart: bText } = getSortableParts(b) + if (!isNaN(aNum) && !isNaN(bNum)) { + return aNum - bNum || aText.localeCompare(bText, undefined, { numeric: true, sensitivity: 'base' }) + } + return aText.localeCompare(bText, undefined, { numeric: true, sensitivity: 'base' }) + }) + } + export const TranscribeOptionsSchema = () => { return OptionsSchema().pick({ include: true, @@ -89,7 +110,7 @@ export const transcribeCommand = async (opts: IKBotTask) => { const info = pathInfoEx(forward_slash(path.resolve(resolve(includePath))), false, { absolute: true, }) - files.push(...default_sort(info.FILES)) + files.push(...info.FILES) } else if (exists(includePath)) { files.push(includePath) } @@ -99,10 +120,12 @@ export const transcribeCommand = async (opts: IKBotTask) => { opts.logger.warn(`No files found for --include patterns: ${opts.include.join(', ')}`) return } - + + files = default_sort(files) + opts.logger.info(`Found ${files.length} files to transcribe.`) - for (const file of files) { + const mapper = async (file: string) => { const fileInfo = path.parse(file) const CWD = process.cwd() const current_variables = { @@ -120,18 +143,32 @@ export const transcribeCommand = async (opts: IKBotTask) => { include: [file], variables: current_variables }; - - if (!itemOpts.dst) { - itemOpts.dst = '${SRC_DIR}/${SRC_NAME}.md'; - } - itemOpts.dst = path.resolve(resolve(itemOpts.dst, itemOpts.alt, itemOpts.variables)) - - opts.logger.info(`Transcribing ${file}...`) - if(itemOpts.dst) { - opts.logger.info(`Output will be saved to ${itemOpts.dst}`) - } + const transcribedText = await transcribe(itemOpts) + return { transcribedText, itemOpts } + }; - await transcribe(itemOpts) + const results = await pMap(files, mapper, { concurrency: 1 }); + + let resolvedDstPath: string | undefined; + if (opts.dst) { + resolvedDstPath = path.resolve(resolve(opts.dst, opts.alt, opts.variables)); + if (fs.existsSync(resolvedDstPath)) { + fs.unlinkSync(resolvedDstPath); + } + const allText = results.map(r => r.transcribedText).filter(Boolean).join('\n\n') + if (allText) { + fs.writeFileSync(resolvedDstPath, allText + '\n'); + opts.logger.info(`Wrote all transcriptions to ${resolvedDstPath}`); + } + } else { + for (const { transcribedText, itemOpts } of results) { + if (transcribedText) { + const defaultDstTemplate = '${SRC_DIR}/${SRC_NAME}.md'; + const defaultDstPath = path.resolve(resolve(defaultDstTemplate, itemOpts.alt, itemOpts.variables)); + fs.writeFileSync(defaultDstPath, transcribedText); + opts.logger.info(`Output will be saved to ${defaultDstPath}`); + } + } } } diff --git a/packages/kbot/src/lib/transcribe.ts b/packages/kbot/src/lib/transcribe.ts index 1f6833c3..03a27a40 100644 --- a/packages/kbot/src/lib/transcribe.ts +++ b/packages/kbot/src/lib/transcribe.ts @@ -15,29 +15,29 @@ const createBuffer = (path: string): Buffer | null => { } } -export const transcribe = async (options: IKBotTask) => { +export const transcribe = async (options: IKBotTask): Promise => { const client = createClient(options) if (!client) { options.logger.error('Failed to create client') - return + return '' } if (!options.include || options.include.length === 0) { options.logger.error('No source file provided via --include') - return; + return ''; } const sourceFile = options.include[0]; if (!exists(sourceFile)) { options.logger.error('Source file does not exist', sourceFile) - return; + return ''; } const file = await toFile(createBuffer(sourceFile), 'audio.mp3', { type: 'audio/mpeg' }); if (!file) { options.logger.error('Error converting source to file') - return; + return ''; } const completion: any = await client.audio.transcriptions.create({ @@ -48,17 +48,9 @@ export const transcribe = async (options: IKBotTask) => { if (!completion) { options.logger.error('OpenAI response is empty') - return; + return ''; } - const text_content = completion.text || ''; - - if (options.dst) { - write(options.dst, text_content) - } else { - process.stdout.write(text_content) - } - - // options.logger.debug('OpenAI Transcribe response:', completion) - return completion + const text_content = completion.text || '' + return text_content } diff --git a/packages/kbot/tests/unit/transcribe/Saturday 13 September 2025 - 002.mp3 b/packages/kbot/tests/unit/transcribe/Saturday 13 September 2025 - 002.mp3 new file mode 100644 index 00000000..8122c6cd Binary files /dev/null and b/packages/kbot/tests/unit/transcribe/Saturday 13 September 2025 - 002.mp3 differ diff --git a/packages/kbot/tests/unit/transcribe/Saturday 13 September 2025 - 003.mp3 b/packages/kbot/tests/unit/transcribe/Saturday 13 September 2025 - 003.mp3 new file mode 100644 index 00000000..aca25977 Binary files /dev/null and b/packages/kbot/tests/unit/transcribe/Saturday 13 September 2025 - 003.mp3 differ diff --git a/packages/kbot/tests/unit/transcribe/Saturday 13 September 2025 - 004.mp3 b/packages/kbot/tests/unit/transcribe/Saturday 13 September 2025 - 004.mp3 new file mode 100644 index 00000000..5308b157 Binary files /dev/null and b/packages/kbot/tests/unit/transcribe/Saturday 13 September 2025 - 004.mp3 differ diff --git a/packages/kbot/tests/unit/transcribe/sequence.md b/packages/kbot/tests/unit/transcribe/sequence.md new file mode 100644 index 00000000..74fcf532 --- /dev/null +++ b/packages/kbot/tests/unit/transcribe/sequence.md @@ -0,0 +1,5 @@ +Sequence one started now. + +Sequence 2 started now. + +The result is 100. diff --git a/packages/kbot/tests/unit/transcribe/test.md b/packages/kbot/tests/unit/transcribe/test.md deleted file mode 100644 index 89640f97..00000000 --- a/packages/kbot/tests/unit/transcribe/test.md +++ /dev/null @@ -1 +0,0 @@ -The lazy fox jumps over the cat. \ No newline at end of file diff --git a/packages/kbot/tests/unit/transcribe/transcribe.test.ts b/packages/kbot/tests/unit/transcribe/transcribe.test.ts index 88d8f8b1..af22bd80 100644 --- a/packages/kbot/tests/unit/transcribe/transcribe.test.ts +++ b/packages/kbot/tests/unit/transcribe/transcribe.test.ts @@ -9,19 +9,26 @@ import { IKBotTask } from '@polymech/ai-tools' const TEST_DATA_DIR = './tests/unit/transcribe' const TEST_MP3 = path.join(TEST_DATA_DIR, 'test.mp3') -const TEST_TIMEOUT = 30000 // 30 seconds +const TEST_TIMEOUT = 60000 // Increased timeout for multiple files describe('Transcribe Command', () => { const defaultOutputFile = path.resolve(path.join(TEST_DATA_DIR, 'test.md')) + const sequenceOutputFile = path.resolve(path.join(TEST_DATA_DIR, 'sequence.md')) - beforeAll(() => { + const cleanupFiles = () => { if (fs.existsSync(defaultOutputFile)) { fs.unlinkSync(defaultOutputFile) } - }) + if (fs.existsSync(sequenceOutputFile)) { + // fs.unlinkSync(sequenceOutputFile) + } + } - it('should transcribe an audio file and save the output to a default markdown file', async () => { + beforeAll(cleanupFiles) + afterAll(cleanupFiles) + + it('should transcribe a single audio file and save the output to a default markdown file', async () => { const options: IKBotTask = { include: [TEST_MP3], router: 'openai', @@ -40,4 +47,26 @@ describe('Transcribe Command', () => { expect(lowerCaseResult).toContain("cat") }, TEST_TIMEOUT) + + it('should transcribe multiple audio files from a glob pattern and append to a single destination file', async () => { + const options: IKBotTask = { + include: [`${TEST_DATA_DIR}/Saturday*.mp3`], + dst: sequenceOutputFile, + router: 'openai', + logLevel: 2, + } + + await transcribeCommand(options); + + expect(exists(sequenceOutputFile)).toBe('file'); + + const result = read(sequenceOutputFile, 'text') as string; + expect(result).toBeDefined(); + + const lowerCaseResult = result.toLowerCase(); + expect(lowerCaseResult).toContain('one'); + expect(lowerCaseResult).toMatch(/two|2/); + expect(lowerCaseResult).toMatch(/hundred|100/); + + }, TEST_TIMEOUT); }) \ No newline at end of file