@redaksjon/protokoll 0.4.3 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.kronologi/config.yaml +10 -0
- package/.kronologi/jobs/monthly-summary/config.yaml +40 -0
- package/.kronologi/jobs/monthly-summary/instructions.md +23 -0
- package/.kronologi/jobs/monthly-summary/persona.md +11 -0
- package/.kronologi/jobs/weekly-summary/config.yaml +42 -0
- package/.kronologi/jobs/weekly-summary/instructions.md +21 -0
- package/.kronologi/jobs/weekly-summary/persona.md +10 -0
- package/README.md +41 -0
- package/activity/2026/4/test-activity.md +10 -0
- package/dist/main.js +2 -2
- package/dist/mcp/server.js +5 -5
- package/dist/mcp/server.js.map +1 -1
- package/dist/term-assist.js +11 -3
- package/dist/term-assist.js.map +1 -1
- package/dist/term-context.js +10 -2
- package/dist/term-context.js.map +1 -1
- package/dist/transcript.js +161 -117
- package/dist/transcript.js.map +1 -1
- package/guide/index.md +6 -0
- package/guide/quickstart.md +26 -1
- package/package.json +1 -1
- package/summary/2026/4/completion.json +16 -0
- package/summary/2026/4/inputs.json +60 -0
- package/summary/2026/4/summary.md +26 -0
package/dist/transcript.js
CHANGED
|
@@ -5,6 +5,8 @@ import path__default from 'node:path';
|
|
|
5
5
|
import * as fs$1 from 'fs/promises';
|
|
6
6
|
import OpenAI$1, { OpenAI } from 'openai';
|
|
7
7
|
import ffmpeg from 'fluent-ffmpeg';
|
|
8
|
+
import * as os from 'node:os';
|
|
9
|
+
import os__default from 'node:os';
|
|
8
10
|
import * as fs from 'node:fs';
|
|
9
11
|
import { glob } from 'glob';
|
|
10
12
|
import crypto from 'node:crypto';
|
|
@@ -13,12 +15,10 @@ import { htmlToText } from 'html-to-text';
|
|
|
13
15
|
import { Command } from 'commander';
|
|
14
16
|
import * as yaml from 'js-yaml';
|
|
15
17
|
import { existsSync, statSync } from 'fs';
|
|
16
|
-
import * as os from 'node:os';
|
|
17
|
-
import os__default from 'node:os';
|
|
18
18
|
import winston from 'winston';
|
|
19
19
|
import { IterationStrategyFactory } from '@riotprompt/riotprompt';
|
|
20
20
|
|
|
21
|
-
const VERSION = "0.
|
|
21
|
+
const VERSION = "1.0.0 (HEAD/9fe7b5f T:v1.0.0 2026-01-24 09:49:02 -0800) linux x64 v24.13.0";
|
|
22
22
|
const PROGRAM_NAME = "protokoll";
|
|
23
23
|
const DEFAULT_DIFF = true;
|
|
24
24
|
const DEFAULT_LOG = false;
|
|
@@ -2950,6 +2950,120 @@ const create$h = (config) => {
|
|
|
2950
2950
|
};
|
|
2951
2951
|
};
|
|
2952
2952
|
|
|
2953
|
+
const ffprobeAsync = (filePath) => {
|
|
2954
|
+
return new Promise((resolve, reject) => {
|
|
2955
|
+
ffmpeg.ffprobe(filePath, (err, metadata) => {
|
|
2956
|
+
if (err) return reject(err);
|
|
2957
|
+
resolve(metadata);
|
|
2958
|
+
});
|
|
2959
|
+
});
|
|
2960
|
+
};
|
|
2961
|
+
const create$g = (logger) => {
|
|
2962
|
+
const storage = create$w({ log: logger.debug });
|
|
2963
|
+
const getAudioCreationTime = async (filePath) => {
|
|
2964
|
+
try {
|
|
2965
|
+
const metadata = await ffprobeAsync(filePath);
|
|
2966
|
+
const formatTags = metadata?.format?.tags;
|
|
2967
|
+
if (formatTags?.creation_time) {
|
|
2968
|
+
logger.debug("Found creation_time in format tags: %s", formatTags.creation_time);
|
|
2969
|
+
return new Date(formatTags.creation_time);
|
|
2970
|
+
}
|
|
2971
|
+
if (metadata?.streams?.length > 0) {
|
|
2972
|
+
for (const stream of metadata.streams) {
|
|
2973
|
+
if (stream.tags?.creation_time) {
|
|
2974
|
+
logger.debug("Found creation_time in stream tags: %s", stream.tags.creation_time);
|
|
2975
|
+
return new Date(stream.tags.creation_time);
|
|
2976
|
+
}
|
|
2977
|
+
}
|
|
2978
|
+
}
|
|
2979
|
+
logger.debug("No creation_time found in audio file metadata");
|
|
2980
|
+
return null;
|
|
2981
|
+
} catch (error) {
|
|
2982
|
+
logger.error("Error extracting creation time from audio file: %s", error);
|
|
2983
|
+
return null;
|
|
2984
|
+
}
|
|
2985
|
+
};
|
|
2986
|
+
const getFileSize = async (filePath) => {
|
|
2987
|
+
try {
|
|
2988
|
+
return await storage.getFileSize(filePath);
|
|
2989
|
+
} catch (error) {
|
|
2990
|
+
logger.error("Error getting file size: %s", error);
|
|
2991
|
+
throw new Error(`Failed to get file size for ${filePath}: ${error}`);
|
|
2992
|
+
}
|
|
2993
|
+
};
|
|
2994
|
+
const splitAudioFile = async (filePath, outputDir, maxSizeBytes) => {
|
|
2995
|
+
try {
|
|
2996
|
+
const metadata = await ffprobeAsync(filePath);
|
|
2997
|
+
const duration = parseFloat(metadata.format.duration);
|
|
2998
|
+
const fileSize = await getFileSize(filePath);
|
|
2999
|
+
const segmentCount = Math.ceil(fileSize / maxSizeBytes);
|
|
3000
|
+
const segmentDuration = duration / segmentCount;
|
|
3001
|
+
logger.debug(`Splitting ${filePath} (${fileSize} bytes) into ${segmentCount} segments of ~${segmentDuration} seconds each`);
|
|
3002
|
+
await storage.createDirectory(outputDir);
|
|
3003
|
+
const outputFiles = [];
|
|
3004
|
+
const fileExt = path__default.extname(filePath);
|
|
3005
|
+
const fileName = path__default.basename(filePath, fileExt);
|
|
3006
|
+
const promises = [];
|
|
3007
|
+
for (let i = 0; i < segmentCount; i++) {
|
|
3008
|
+
const startTime = i * segmentDuration;
|
|
3009
|
+
const outputPath = path__default.join(outputDir, `${fileName}_part${i + 1}${fileExt}`);
|
|
3010
|
+
outputFiles.push(outputPath);
|
|
3011
|
+
const promise = new Promise((resolve, reject) => {
|
|
3012
|
+
ffmpeg(filePath).setStartTime(startTime).setDuration(segmentDuration).output(outputPath).on("end", () => {
|
|
3013
|
+
logger.debug(`Created segment ${i + 1}/${segmentCount}: ${outputPath}`);
|
|
3014
|
+
resolve();
|
|
3015
|
+
}).on("error", (err) => {
|
|
3016
|
+
logger.error(`Error creating segment ${i + 1}/${segmentCount}: ${err}`);
|
|
3017
|
+
reject(err);
|
|
3018
|
+
}).run();
|
|
3019
|
+
});
|
|
3020
|
+
promises.push(promise);
|
|
3021
|
+
}
|
|
3022
|
+
await Promise.all(promises);
|
|
3023
|
+
return outputFiles;
|
|
3024
|
+
} catch (error) {
|
|
3025
|
+
logger.error("Error splitting audio file: %s", error);
|
|
3026
|
+
throw new Error(`Failed to split audio file ${filePath}: ${error}`);
|
|
3027
|
+
}
|
|
3028
|
+
};
|
|
3029
|
+
const convertToSupportedFormat = async (filePath, outputDir) => {
|
|
3030
|
+
try {
|
|
3031
|
+
const fileExt = path__default.extname(filePath).toLowerCase();
|
|
3032
|
+
const supportedFormats = [".flac", ".m4a", ".mp3", ".mp4", ".mpeg", ".mpga", ".oga", ".ogg", ".wav", ".webm"];
|
|
3033
|
+
if (supportedFormats.includes(fileExt)) {
|
|
3034
|
+
logger.debug(`File ${filePath} is already in a supported format: ${fileExt}`);
|
|
3035
|
+
return filePath;
|
|
3036
|
+
}
|
|
3037
|
+
logger.info(`Converting ${fileExt} file to mp3 for transcription...`);
|
|
3038
|
+
const fileName = path__default.basename(filePath, fileExt);
|
|
3039
|
+
const outputPath = path__default.join(outputDir, `${fileName}.mp3`);
|
|
3040
|
+
if (await storage.exists(outputPath)) {
|
|
3041
|
+
logger.debug(`Converted file already exists: ${outputPath}`);
|
|
3042
|
+
return outputPath;
|
|
3043
|
+
}
|
|
3044
|
+
await storage.createDirectory(outputDir);
|
|
3045
|
+
return new Promise((resolve, reject) => {
|
|
3046
|
+
ffmpeg(filePath).toFormat("mp3").audioBitrate("128k").output(outputPath).on("end", () => {
|
|
3047
|
+
logger.info(`Successfully converted to: ${outputPath}`);
|
|
3048
|
+
resolve(outputPath);
|
|
3049
|
+
}).on("error", (err) => {
|
|
3050
|
+
logger.error(`Error converting audio file: ${err}`);
|
|
3051
|
+
reject(new Error(`Failed to convert ${filePath} to mp3: ${err.message}`));
|
|
3052
|
+
}).run();
|
|
3053
|
+
});
|
|
3054
|
+
} catch (error) {
|
|
3055
|
+
logger.error("Error in convertToSupportedFormat: %s", error);
|
|
3056
|
+
throw new Error(`Failed to convert audio file ${filePath}: ${error}`);
|
|
3057
|
+
}
|
|
3058
|
+
};
|
|
3059
|
+
return {
|
|
3060
|
+
getAudioCreationTime,
|
|
3061
|
+
getFileSize,
|
|
3062
|
+
splitAudioFile,
|
|
3063
|
+
convertToSupportedFormat
|
|
3064
|
+
};
|
|
3065
|
+
};
|
|
3066
|
+
|
|
2953
3067
|
const MODEL_CAPABILITIES = {
|
|
2954
3068
|
"whisper-1": {
|
|
2955
3069
|
supportsStreaming: false,
|
|
@@ -2974,9 +3088,10 @@ const MODEL_CAPABILITIES = {
|
|
|
2974
3088
|
}
|
|
2975
3089
|
};
|
|
2976
3090
|
|
|
2977
|
-
const create$
|
|
3091
|
+
const create$f = (openai) => {
|
|
2978
3092
|
const logger = getLogger();
|
|
2979
3093
|
const storage = create$w({ log: logger.debug });
|
|
3094
|
+
const media = create$g(logger);
|
|
2980
3095
|
const supportsStreaming = (model) => {
|
|
2981
3096
|
return MODEL_CAPABILITIES[model]?.supportsStreaming ?? false;
|
|
2982
3097
|
};
|
|
@@ -2986,7 +3101,10 @@ const create$g = (openai) => {
|
|
|
2986
3101
|
const transcribe = async (request) => {
|
|
2987
3102
|
const { audioFile, config } = request;
|
|
2988
3103
|
logger.debug("Starting transcription", { model: config.model, file: audioFile });
|
|
2989
|
-
const
|
|
3104
|
+
const tempDir = path.join(os.tmpdir(), "protokoll-conversions");
|
|
3105
|
+
const convertedAudioFile = await media.convertToSupportedFormat(audioFile, tempDir);
|
|
3106
|
+
logger.debug(`Using audio file for transcription: ${convertedAudioFile}`);
|
|
3107
|
+
const audioStream = await storage.readStream(convertedAudioFile);
|
|
2990
3108
|
const startTime = Date.now();
|
|
2991
3109
|
const response = await openai.audio.transcriptions.create({
|
|
2992
3110
|
model: config.model,
|
|
@@ -3011,12 +3129,12 @@ const create$g = (openai) => {
|
|
|
3011
3129
|
};
|
|
3012
3130
|
};
|
|
3013
3131
|
|
|
3014
|
-
const create$
|
|
3132
|
+
const create$e = (options = {}) => {
|
|
3015
3133
|
let service = null;
|
|
3016
3134
|
const getService = () => {
|
|
3017
3135
|
if (!service) {
|
|
3018
3136
|
const openai = options.openaiClient ?? new OpenAI$1({ apiKey: options.apiKey });
|
|
3019
|
-
service = create$
|
|
3137
|
+
service = create$f(openai);
|
|
3020
3138
|
}
|
|
3021
3139
|
return service;
|
|
3022
3140
|
};
|
|
@@ -3041,7 +3159,7 @@ const create$f = (options = {}) => {
|
|
|
3041
3159
|
};
|
|
3042
3160
|
};
|
|
3043
3161
|
|
|
3044
|
-
const create$
|
|
3162
|
+
const create$d = (config) => {
|
|
3045
3163
|
const logger = getLogger();
|
|
3046
3164
|
let client = null;
|
|
3047
3165
|
const getClient = () => {
|
|
@@ -3270,8 +3388,8 @@ const getRecommendedStrategy = (transcriptLength, hasUnknownNames, complexity) =
|
|
|
3270
3388
|
return "adaptive";
|
|
3271
3389
|
};
|
|
3272
3390
|
|
|
3273
|
-
const create$
|
|
3274
|
-
const client = create$
|
|
3391
|
+
const create$c = (config) => {
|
|
3392
|
+
const client = create$d(config);
|
|
3275
3393
|
return {
|
|
3276
3394
|
complete: (request) => client.complete(request),
|
|
3277
3395
|
completeWithTools: (request) => client.completeWithTools(request),
|
|
@@ -3352,7 +3470,7 @@ function extractNameContext(transcript, name) {
|
|
|
3352
3470
|
}
|
|
3353
3471
|
return context;
|
|
3354
3472
|
}
|
|
3355
|
-
const create$
|
|
3473
|
+
const create$b = (ctx) => ({
|
|
3356
3474
|
name: "lookup_person",
|
|
3357
3475
|
description: "Look up information about a person mentioned in the transcript. Use when you encounter a name that might need spelling verification or additional context.",
|
|
3358
3476
|
parameters: {
|
|
@@ -3501,7 +3619,7 @@ function extractTermContext(transcript, term) {
|
|
|
3501
3619
|
}
|
|
3502
3620
|
return context;
|
|
3503
3621
|
}
|
|
3504
|
-
const create$
|
|
3622
|
+
const create$a = (ctx) => ({
|
|
3505
3623
|
name: "lookup_project",
|
|
3506
3624
|
description: "Look up project information for routing and context. Use when you need to determine where this note should be filed.",
|
|
3507
3625
|
parameters: {
|
|
@@ -3670,7 +3788,7 @@ const create$b = (ctx) => ({
|
|
|
3670
3788
|
}
|
|
3671
3789
|
});
|
|
3672
3790
|
|
|
3673
|
-
const create$
|
|
3791
|
+
const create$9 = (ctx) => ({
|
|
3674
3792
|
name: "verify_spelling",
|
|
3675
3793
|
description: "Request user verification for an unknown name or term. Use when you encounter something that needs human confirmation.",
|
|
3676
3794
|
parameters: {
|
|
@@ -3717,7 +3835,7 @@ Please provide the correct spelling:`,
|
|
|
3717
3835
|
}
|
|
3718
3836
|
});
|
|
3719
3837
|
|
|
3720
|
-
const create$
|
|
3838
|
+
const create$8 = (ctx) => ({
|
|
3721
3839
|
name: "route_note",
|
|
3722
3840
|
description: "Determine the destination for this note based on content analysis.",
|
|
3723
3841
|
parameters: {
|
|
@@ -3760,7 +3878,7 @@ const create$9 = (ctx) => ({
|
|
|
3760
3878
|
}
|
|
3761
3879
|
});
|
|
3762
3880
|
|
|
3763
|
-
const create$
|
|
3881
|
+
const create$7 = (_ctx) => ({
|
|
3764
3882
|
name: "store_context",
|
|
3765
3883
|
description: "Store new context information for future use. Use when you learn something new that should be remembered.",
|
|
3766
3884
|
parameters: {
|
|
@@ -3795,13 +3913,13 @@ const create$8 = (_ctx) => ({
|
|
|
3795
3913
|
}
|
|
3796
3914
|
});
|
|
3797
3915
|
|
|
3798
|
-
const create$
|
|
3916
|
+
const create$6 = (ctx) => {
|
|
3799
3917
|
const tools = [
|
|
3800
|
-
create$c(ctx),
|
|
3801
3918
|
create$b(ctx),
|
|
3802
3919
|
create$a(ctx),
|
|
3803
3920
|
create$9(ctx),
|
|
3804
|
-
create$8()
|
|
3921
|
+
create$8(ctx),
|
|
3922
|
+
create$7()
|
|
3805
3923
|
];
|
|
3806
3924
|
const toolMap = new Map(tools.map((t) => [t.name, t]));
|
|
3807
3925
|
return {
|
|
@@ -3845,9 +3963,9 @@ const cleanResponseContent = (content) => {
|
|
|
3845
3963
|
}
|
|
3846
3964
|
return cleaned.trim();
|
|
3847
3965
|
};
|
|
3848
|
-
const create$
|
|
3966
|
+
const create$5 = (reasoning, ctx) => {
|
|
3849
3967
|
const logger = getLogger();
|
|
3850
|
-
const registry = create$
|
|
3968
|
+
const registry = create$6(ctx);
|
|
3851
3969
|
const process = async (transcriptText) => {
|
|
3852
3970
|
const state = {
|
|
3853
3971
|
originalText: transcriptText,
|
|
@@ -4515,18 +4633,18 @@ CRITICAL: Your response must contain ONLY the corrected transcript text - absolu
|
|
|
4515
4633
|
return { process };
|
|
4516
4634
|
};
|
|
4517
4635
|
|
|
4518
|
-
const create$
|
|
4519
|
-
const executor = create$
|
|
4636
|
+
const create$4 = (reasoning, toolContext) => {
|
|
4637
|
+
const executor = create$5(reasoning, toolContext);
|
|
4520
4638
|
return {
|
|
4521
4639
|
process: (transcriptText) => executor.process(transcriptText),
|
|
4522
4640
|
getAvailableTools: () => {
|
|
4523
|
-
const registry = create$
|
|
4641
|
+
const registry = create$6(toolContext);
|
|
4524
4642
|
return registry.getTools().map((t) => t.name);
|
|
4525
4643
|
}
|
|
4526
4644
|
};
|
|
4527
4645
|
};
|
|
4528
4646
|
|
|
4529
|
-
const create$
|
|
4647
|
+
const create$3 = (config) => {
|
|
4530
4648
|
const logger = getLogger();
|
|
4531
4649
|
const storage = create$w({ log: logger.debug });
|
|
4532
4650
|
const buildDirectoryPath = (date) => {
|
|
@@ -4623,7 +4741,7 @@ const create$4 = (config) => {
|
|
|
4623
4741
|
};
|
|
4624
4742
|
};
|
|
4625
4743
|
|
|
4626
|
-
const create$
|
|
4744
|
+
const create$2 = async (config) => {
|
|
4627
4745
|
const logger = getLogger();
|
|
4628
4746
|
const currentWorkingDir = globalThis.process.cwd();
|
|
4629
4747
|
logger.debug("Initializing intelligent transcription pipeline...");
|
|
@@ -4672,16 +4790,16 @@ const create$3 = async (config) => {
|
|
|
4672
4790
|
if (reflection) {
|
|
4673
4791
|
logger.debug("Self-reflection system enabled");
|
|
4674
4792
|
}
|
|
4675
|
-
const transcription = create$
|
|
4793
|
+
const transcription = create$e({
|
|
4676
4794
|
defaultModel: config.transcriptionModel
|
|
4677
4795
|
});
|
|
4678
4796
|
logger.debug("Transcription service initialized with model: %s", config.transcriptionModel);
|
|
4679
|
-
const reasoning = create$
|
|
4797
|
+
const reasoning = create$c({
|
|
4680
4798
|
model: config.model,
|
|
4681
4799
|
reasoningLevel: config.reasoningLevel
|
|
4682
4800
|
});
|
|
4683
4801
|
logger.debug("Reasoning system initialized with model: %s, reasoning level: %s", config.model, config.reasoningLevel || "medium");
|
|
4684
|
-
const complete = config.processedDirectory ? create$
|
|
4802
|
+
const complete = config.processedDirectory ? create$3({
|
|
4685
4803
|
processedDirectory: config.processedDirectory,
|
|
4686
4804
|
outputStructure: config.outputStructure,
|
|
4687
4805
|
dryRun: config.dryRun
|
|
@@ -4800,7 +4918,7 @@ const create$3 = async (config) => {
|
|
|
4800
4918
|
// Always pass interactive handler - it will handle enabled/disabled internally
|
|
4801
4919
|
interactiveInstance: interactive
|
|
4802
4920
|
};
|
|
4803
|
-
const executor = create$
|
|
4921
|
+
const executor = create$4(reasoning, toolContext);
|
|
4804
4922
|
const agenticResult = await executor.process(state.rawTranscript || "");
|
|
4805
4923
|
state.enhancedText = agenticResult.enhancedText;
|
|
4806
4924
|
const toolsUsed = agenticResult.toolsUsed;
|
|
@@ -4982,91 +5100,8 @@ const create$3 = async (config) => {
|
|
|
4982
5100
|
return { process: processInput };
|
|
4983
5101
|
};
|
|
4984
5102
|
|
|
4985
|
-
const create$
|
|
4986
|
-
return create$
|
|
4987
|
-
};
|
|
4988
|
-
|
|
4989
|
-
const ffprobeAsync = (filePath) => {
|
|
4990
|
-
return new Promise((resolve, reject) => {
|
|
4991
|
-
ffmpeg.ffprobe(filePath, (err, metadata) => {
|
|
4992
|
-
if (err) return reject(err);
|
|
4993
|
-
resolve(metadata);
|
|
4994
|
-
});
|
|
4995
|
-
});
|
|
4996
|
-
};
|
|
4997
|
-
const create$1 = (logger) => {
|
|
4998
|
-
const storage = create$w({ log: logger.debug });
|
|
4999
|
-
const getAudioCreationTime = async (filePath) => {
|
|
5000
|
-
try {
|
|
5001
|
-
const metadata = await ffprobeAsync(filePath);
|
|
5002
|
-
const formatTags = metadata?.format?.tags;
|
|
5003
|
-
if (formatTags?.creation_time) {
|
|
5004
|
-
logger.debug("Found creation_time in format tags: %s", formatTags.creation_time);
|
|
5005
|
-
return new Date(formatTags.creation_time);
|
|
5006
|
-
}
|
|
5007
|
-
if (metadata?.streams?.length > 0) {
|
|
5008
|
-
for (const stream of metadata.streams) {
|
|
5009
|
-
if (stream.tags?.creation_time) {
|
|
5010
|
-
logger.debug("Found creation_time in stream tags: %s", stream.tags.creation_time);
|
|
5011
|
-
return new Date(stream.tags.creation_time);
|
|
5012
|
-
}
|
|
5013
|
-
}
|
|
5014
|
-
}
|
|
5015
|
-
logger.debug("No creation_time found in audio file metadata");
|
|
5016
|
-
return null;
|
|
5017
|
-
} catch (error) {
|
|
5018
|
-
logger.error("Error extracting creation time from audio file: %s", error);
|
|
5019
|
-
return null;
|
|
5020
|
-
}
|
|
5021
|
-
};
|
|
5022
|
-
const getFileSize = async (filePath) => {
|
|
5023
|
-
try {
|
|
5024
|
-
return await storage.getFileSize(filePath);
|
|
5025
|
-
} catch (error) {
|
|
5026
|
-
logger.error("Error getting file size: %s", error);
|
|
5027
|
-
throw new Error(`Failed to get file size for ${filePath}: ${error}`);
|
|
5028
|
-
}
|
|
5029
|
-
};
|
|
5030
|
-
const splitAudioFile = async (filePath, outputDir, maxSizeBytes) => {
|
|
5031
|
-
try {
|
|
5032
|
-
const metadata = await ffprobeAsync(filePath);
|
|
5033
|
-
const duration = parseFloat(metadata.format.duration);
|
|
5034
|
-
const fileSize = await getFileSize(filePath);
|
|
5035
|
-
const segmentCount = Math.ceil(fileSize / maxSizeBytes);
|
|
5036
|
-
const segmentDuration = duration / segmentCount;
|
|
5037
|
-
logger.debug(`Splitting ${filePath} (${fileSize} bytes) into ${segmentCount} segments of ~${segmentDuration} seconds each`);
|
|
5038
|
-
await storage.createDirectory(outputDir);
|
|
5039
|
-
const outputFiles = [];
|
|
5040
|
-
const fileExt = path__default.extname(filePath);
|
|
5041
|
-
const fileName = path__default.basename(filePath, fileExt);
|
|
5042
|
-
const promises = [];
|
|
5043
|
-
for (let i = 0; i < segmentCount; i++) {
|
|
5044
|
-
const startTime = i * segmentDuration;
|
|
5045
|
-
const outputPath = path__default.join(outputDir, `${fileName}_part${i + 1}${fileExt}`);
|
|
5046
|
-
outputFiles.push(outputPath);
|
|
5047
|
-
const promise = new Promise((resolve, reject) => {
|
|
5048
|
-
ffmpeg(filePath).setStartTime(startTime).setDuration(segmentDuration).output(outputPath).on("end", () => {
|
|
5049
|
-
logger.debug(`Created segment ${i + 1}/${segmentCount}: ${outputPath}`);
|
|
5050
|
-
resolve();
|
|
5051
|
-
}).on("error", (err) => {
|
|
5052
|
-
logger.error(`Error creating segment ${i + 1}/${segmentCount}: ${err}`);
|
|
5053
|
-
reject(err);
|
|
5054
|
-
}).run();
|
|
5055
|
-
});
|
|
5056
|
-
promises.push(promise);
|
|
5057
|
-
}
|
|
5058
|
-
await Promise.all(promises);
|
|
5059
|
-
return outputFiles;
|
|
5060
|
-
} catch (error) {
|
|
5061
|
-
logger.error("Error splitting audio file: %s", error);
|
|
5062
|
-
throw new Error(`Failed to split audio file ${filePath}: ${error}`);
|
|
5063
|
-
}
|
|
5064
|
-
};
|
|
5065
|
-
return {
|
|
5066
|
-
getAudioCreationTime,
|
|
5067
|
-
getFileSize,
|
|
5068
|
-
splitAudioFile
|
|
5069
|
-
};
|
|
5103
|
+
const create$1 = async (config) => {
|
|
5104
|
+
return create$2(config);
|
|
5070
5105
|
};
|
|
5071
5106
|
|
|
5072
5107
|
const create = (config) => {
|
|
@@ -5249,10 +5284,19 @@ Respond ONLY with valid JSON in this exact format:
|
|
|
5249
5284
|
isAvailable
|
|
5250
5285
|
};
|
|
5251
5286
|
};
|
|
5287
|
+
const withProgress = async (message, operation, print) => {
|
|
5288
|
+
print(`[${message}...]`);
|
|
5289
|
+
try {
|
|
5290
|
+
const result = await operation();
|
|
5291
|
+
return result;
|
|
5292
|
+
} finally {
|
|
5293
|
+
}
|
|
5294
|
+
};
|
|
5252
5295
|
|
|
5253
5296
|
const projectAssist = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
|
|
5254
5297
|
__proto__: null,
|
|
5255
|
-
create
|
|
5298
|
+
create,
|
|
5299
|
+
withProgress
|
|
5256
5300
|
}, Symbol.toStringTag, { value: 'Module' }));
|
|
5257
5301
|
|
|
5258
5302
|
const print$1 = (text) => process.stdout.write(text + "\n");
|
|
@@ -6392,7 +6436,7 @@ const runFeedback = async (transcriptPath, options) => {
|
|
|
6392
6436
|
}
|
|
6393
6437
|
const transcriptContent = await fs$1.readFile(transcriptPath, "utf-8");
|
|
6394
6438
|
const context = await create$u();
|
|
6395
|
-
const reasoning = create$
|
|
6439
|
+
const reasoning = create$c({ model: options.model || DEFAULT_MODEL });
|
|
6396
6440
|
const feedbackCtx = {
|
|
6397
6441
|
transcriptPath,
|
|
6398
6442
|
transcriptContent,
|
|
@@ -6798,5 +6842,5 @@ const registerTranscriptCommands = (program) => {
|
|
|
6798
6842
|
});
|
|
6799
6843
|
};
|
|
6800
6844
|
|
|
6801
|
-
export { ALLOWED_OUTPUT_FILENAME_OPTIONS as A, listTranscripts as B, DEFAULT_TEMP_DIRECTORY as C, DEFAULT_REASONING_LEVEL as D, create$p as E, create$
|
|
6845
|
+
export { ALLOWED_OUTPUT_FILENAME_OPTIONS as A, listTranscripts as B, DEFAULT_TEMP_DIRECTORY as C, DEFAULT_REASONING_LEVEL as D, create$p as E, create$c as F, processFeedback as G, applyChanges as H, combineTranscripts as I, editTranscript as J, parseTranscript as K, createCompletion as L, contentFetcher as M, projectAssist as N, PROGRAM_NAME as P, VERSION as V, PROTOKOLL_DEFAULTS as a, DEFAULT_MAX_AUDIO_SIZE as b, create$w as c, create$g as d, DEFAULT_INTERMEDIATE_DIRECTORY as e, ALLOWED_OUTPUT_STRUCTURES as f, getLogger as g, ALLOWED_AUDIO_EXTENSIONS as h, DEFAULT_OUTPUT_DIRECTORY as i, DEFAULT_INPUT_DIRECTORY as j, DEFAULT_OUTPUT_FILENAME_OPTIONS as k, DEFAULT_OUTPUT_STRUCTURE as l, DEFAULT_AUDIO_EXTENSIONS as m, DEFAULT_TIMEZONE as n, DEFAULT_CONFIG_DIR as o, create$1 as p, create$u as q, create as r, setLogLevel as s, DEFAULT_CONTEXT_DIR_NAME as t, DEFAULT_CONTEXT_CONFIG_FILE_NAME as u, DEFAULT_MODEL as v, DEFAULT_TRANSCRIPTION_MODEL as w, registerActionCommands as x, registerFeedbackCommands as y, registerTranscriptCommands as z };
|
|
6802
6846
|
//# sourceMappingURL=transcript.js.map
|