codeharbor 0.1.21 → 0.1.22
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/.env.example +4 -0
- package/README.md +13 -5
- package/dist/cli.js +190 -15
- package/package.json +1 -1
package/.env.example
CHANGED
|
@@ -68,6 +68,10 @@ CLI_COMPAT_TRANSCRIBE_AUDIO=false
|
|
|
68
68
|
CLI_COMPAT_AUDIO_TRANSCRIBE_MODEL=gpt-4o-mini-transcribe
|
|
69
69
|
CLI_COMPAT_AUDIO_TRANSCRIBE_TIMEOUT_MS=120000
|
|
70
70
|
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_CHARS=6000
|
|
71
|
+
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_RETRIES=1
|
|
72
|
+
CLI_COMPAT_AUDIO_TRANSCRIBE_RETRY_DELAY_MS=800
|
|
73
|
+
# Skip transcription when audio file is larger than this limit (bytes). Default: 25MB.
|
|
74
|
+
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_BYTES=26214400
|
|
71
75
|
# Optional local whisper command. Use {input} placeholder for the audio file path.
|
|
72
76
|
# Example:
|
|
73
77
|
# CLI_COMPAT_AUDIO_LOCAL_WHISPER_COMMAND=codeharbor-whisper-transcribe --input {input} --model small
|
package/README.md
CHANGED
|
@@ -468,6 +468,12 @@ To make IM behavior closer to local `codex` CLI interaction, enable:
|
|
|
468
468
|
- timeout for each audio transcription request
|
|
469
469
|
- `CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_CHARS`
|
|
470
470
|
- max transcript length appended to prompt for one attachment
|
|
471
|
+
- `CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_RETRIES`
|
|
472
|
+
- retry count for local/OpenAI transcription failures (default `1`)
|
|
473
|
+
- `CLI_COMPAT_AUDIO_TRANSCRIBE_RETRY_DELAY_MS`
|
|
474
|
+
- base retry delay between attempts
|
|
475
|
+
- `CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_BYTES`
|
|
476
|
+
- skip transcription when attachment is larger than this size
|
|
471
477
|
- `CLI_COMPAT_AUDIO_LOCAL_WHISPER_COMMAND`
|
|
472
478
|
- optional local whisper command template (use `{input}` placeholder for audio file path)
|
|
473
479
|
- helper command shipped by package: `codeharbor-whisper-transcribe --input {input} --model small`
|
|
@@ -519,11 +525,13 @@ When image attachments are present and `CLI_COMPAT_FETCH_MEDIA=true`, CodeHarbor
|
|
|
519
525
|
When audio attachments are present and both `CLI_COMPAT_FETCH_MEDIA=true` and `CLI_COMPAT_TRANSCRIBE_AUDIO=true`, CodeHarbor will:
|
|
520
526
|
|
|
521
527
|
1. download `m.audio` media to a temp file
|
|
522
|
-
2.
|
|
523
|
-
3. if
|
|
524
|
-
4.
|
|
525
|
-
5.
|
|
526
|
-
6.
|
|
528
|
+
2. skip oversized audio files based on `CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_BYTES`
|
|
529
|
+
3. if `CLI_COMPAT_AUDIO_LOCAL_WHISPER_COMMAND` is configured, execute local whisper first
|
|
530
|
+
4. if local whisper fails and `OPENAI_API_KEY` is available, fallback to OpenAI transcription API
|
|
531
|
+
5. retry transient failures using `CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_RETRIES`
|
|
532
|
+
6. append transcript to `[audio_transcripts]` prompt block
|
|
533
|
+
7. continue request even if transcription fails (warn log + no transcript)
|
|
534
|
+
8. best-effort cleanup temp files after the request
|
|
527
535
|
|
|
528
536
|
`OPENAI_API_KEY` is optional when local whisper command is configured, and required only for OpenAI fallback.
|
|
529
537
|
For `codeharbor-whisper-transcribe`, install runtime first: `python3 -m pip install faster-whisper`.
|
package/dist/cli.js
CHANGED
|
@@ -366,6 +366,18 @@ var ADMIN_CONSOLE_HTML = `<!doctype html>
|
|
|
366
366
|
<span class="field-label">Audio transcript max chars</span>
|
|
367
367
|
<input id="global-cli-audio-max-chars" type="number" min="1" />
|
|
368
368
|
</label>
|
|
369
|
+
<label class="field">
|
|
370
|
+
<span class="field-label">Audio transcribe max retries</span>
|
|
371
|
+
<input id="global-cli-audio-max-retries" type="number" min="0" max="10" />
|
|
372
|
+
</label>
|
|
373
|
+
<label class="field">
|
|
374
|
+
<span class="field-label">Audio transcribe retry delay (ms)</span>
|
|
375
|
+
<input id="global-cli-audio-retry-delay" type="number" min="0" />
|
|
376
|
+
</label>
|
|
377
|
+
<label class="field">
|
|
378
|
+
<span class="field-label">Audio max bytes</span>
|
|
379
|
+
<input id="global-cli-audio-max-bytes" type="number" min="1" />
|
|
380
|
+
</label>
|
|
369
381
|
<label class="field">
|
|
370
382
|
<span class="field-label">Local whisper command</span>
|
|
371
383
|
<input id="global-cli-audio-local-command" type="text" placeholder='python3 /opt/whisper/transcribe.py --input {input}' />
|
|
@@ -712,6 +724,11 @@ var ADMIN_CONSOLE_HTML = `<!doctype html>
|
|
|
712
724
|
document.getElementById("global-cli-audio-model").value = cliCompat.audioTranscribeModel || "gpt-4o-mini-transcribe";
|
|
713
725
|
document.getElementById("global-cli-audio-timeout").value = String(cliCompat.audioTranscribeTimeoutMs || 120000);
|
|
714
726
|
document.getElementById("global-cli-audio-max-chars").value = String(cliCompat.audioTranscribeMaxChars || 6000);
|
|
727
|
+
document.getElementById("global-cli-audio-max-retries").value = String(
|
|
728
|
+
typeof cliCompat.audioTranscribeMaxRetries === "number" ? cliCompat.audioTranscribeMaxRetries : 1
|
|
729
|
+
);
|
|
730
|
+
document.getElementById("global-cli-audio-retry-delay").value = String(cliCompat.audioTranscribeRetryDelayMs || 800);
|
|
731
|
+
document.getElementById("global-cli-audio-max-bytes").value = String(cliCompat.audioTranscribeMaxBytes || 26214400);
|
|
715
732
|
document.getElementById("global-cli-audio-local-command").value = cliCompat.audioLocalWhisperCommand || "";
|
|
716
733
|
document.getElementById("global-cli-audio-local-timeout").value = String(cliCompat.audioLocalWhisperTimeoutMs || 180000);
|
|
717
734
|
document.getElementById("global-agent-enabled").checked = Boolean(agentWorkflow.enabled);
|
|
@@ -760,6 +777,9 @@ var ADMIN_CONSOLE_HTML = `<!doctype html>
|
|
|
760
777
|
audioTranscribeModel: asText("global-cli-audio-model") || "gpt-4o-mini-transcribe",
|
|
761
778
|
audioTranscribeTimeoutMs: asNumber("global-cli-audio-timeout", 120000),
|
|
762
779
|
audioTranscribeMaxChars: asNumber("global-cli-audio-max-chars", 6000),
|
|
780
|
+
audioTranscribeMaxRetries: asNumber("global-cli-audio-max-retries", 1),
|
|
781
|
+
audioTranscribeRetryDelayMs: asNumber("global-cli-audio-retry-delay", 800),
|
|
782
|
+
audioTranscribeMaxBytes: asNumber("global-cli-audio-max-bytes", 26214400),
|
|
763
783
|
audioLocalWhisperCommand: asText("global-cli-audio-local-command"),
|
|
764
784
|
audioLocalWhisperTimeoutMs: asNumber("global-cli-audio-local-timeout", 180000)
|
|
765
785
|
},
|
|
@@ -2037,6 +2057,37 @@ var AdminServer = class {
|
|
|
2037
2057
|
envUpdates.CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_CHARS = String(value);
|
|
2038
2058
|
updatedKeys.push("cliCompat.audioTranscribeMaxChars");
|
|
2039
2059
|
}
|
|
2060
|
+
if ("audioTranscribeMaxRetries" in compat) {
|
|
2061
|
+
const value = normalizePositiveInt(
|
|
2062
|
+
compat.audioTranscribeMaxRetries,
|
|
2063
|
+
this.config.cliCompat.audioTranscribeMaxRetries,
|
|
2064
|
+
0,
|
|
2065
|
+
10
|
|
2066
|
+
);
|
|
2067
|
+
this.config.cliCompat.audioTranscribeMaxRetries = value;
|
|
2068
|
+
envUpdates.CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_RETRIES = String(value);
|
|
2069
|
+
updatedKeys.push("cliCompat.audioTranscribeMaxRetries");
|
|
2070
|
+
}
|
|
2071
|
+
if ("audioTranscribeRetryDelayMs" in compat) {
|
|
2072
|
+
const value = normalizeNonNegativeInt(
|
|
2073
|
+
compat.audioTranscribeRetryDelayMs,
|
|
2074
|
+
this.config.cliCompat.audioTranscribeRetryDelayMs
|
|
2075
|
+
);
|
|
2076
|
+
this.config.cliCompat.audioTranscribeRetryDelayMs = value;
|
|
2077
|
+
envUpdates.CLI_COMPAT_AUDIO_TRANSCRIBE_RETRY_DELAY_MS = String(value);
|
|
2078
|
+
updatedKeys.push("cliCompat.audioTranscribeRetryDelayMs");
|
|
2079
|
+
}
|
|
2080
|
+
if ("audioTranscribeMaxBytes" in compat) {
|
|
2081
|
+
const value = normalizePositiveInt(
|
|
2082
|
+
compat.audioTranscribeMaxBytes,
|
|
2083
|
+
this.config.cliCompat.audioTranscribeMaxBytes,
|
|
2084
|
+
1,
|
|
2085
|
+
Number.MAX_SAFE_INTEGER
|
|
2086
|
+
);
|
|
2087
|
+
this.config.cliCompat.audioTranscribeMaxBytes = value;
|
|
2088
|
+
envUpdates.CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_BYTES = String(value);
|
|
2089
|
+
updatedKeys.push("cliCompat.audioTranscribeMaxBytes");
|
|
2090
|
+
}
|
|
2040
2091
|
if ("audioLocalWhisperCommand" in compat) {
|
|
2041
2092
|
const value = normalizeString(
|
|
2042
2093
|
compat.audioLocalWhisperCommand,
|
|
@@ -3753,12 +3804,15 @@ var import_promises3 = __toESM(require("fs/promises"));
|
|
|
3753
3804
|
var import_node_path8 = __toESM(require("path"));
|
|
3754
3805
|
var import_node_util3 = require("util");
|
|
3755
3806
|
var execAsync = (0, import_node_util3.promisify)(import_node_child_process5.exec);
|
|
3807
|
+
var RETRYABLE_OPENAI_STATUS = /* @__PURE__ */ new Set([408, 425, 429, 500, 502, 503, 504]);
|
|
3756
3808
|
var AudioTranscriber = class {
|
|
3757
3809
|
enabled;
|
|
3758
3810
|
apiKey;
|
|
3759
3811
|
model;
|
|
3760
3812
|
timeoutMs;
|
|
3761
3813
|
maxChars;
|
|
3814
|
+
maxRetries;
|
|
3815
|
+
retryDelayMs;
|
|
3762
3816
|
localWhisperCommand;
|
|
3763
3817
|
localWhisperTimeoutMs;
|
|
3764
3818
|
constructor(options) {
|
|
@@ -3767,6 +3821,8 @@ var AudioTranscriber = class {
|
|
|
3767
3821
|
this.model = options.model;
|
|
3768
3822
|
this.timeoutMs = options.timeoutMs;
|
|
3769
3823
|
this.maxChars = options.maxChars;
|
|
3824
|
+
this.maxRetries = options.maxRetries;
|
|
3825
|
+
this.retryDelayMs = options.retryDelayMs;
|
|
3770
3826
|
this.localWhisperCommand = options.localWhisperCommand;
|
|
3771
3827
|
this.localWhisperTimeoutMs = options.localWhisperTimeoutMs;
|
|
3772
3828
|
}
|
|
@@ -3808,7 +3864,7 @@ var AudioTranscriber = class {
|
|
|
3808
3864
|
let localError = null;
|
|
3809
3865
|
if (hasLocalWhisper) {
|
|
3810
3866
|
try {
|
|
3811
|
-
const localText = await this.
|
|
3867
|
+
const localText = await this.transcribeOneWithLocalWhisperWithRetry(attachment);
|
|
3812
3868
|
if (localText) {
|
|
3813
3869
|
return localText;
|
|
3814
3870
|
}
|
|
@@ -3818,7 +3874,7 @@ var AudioTranscriber = class {
|
|
|
3818
3874
|
}
|
|
3819
3875
|
if (hasOpenAi) {
|
|
3820
3876
|
try {
|
|
3821
|
-
return await this.
|
|
3877
|
+
return await this.transcribeOneWithOpenAiWithRetry(attachment);
|
|
3822
3878
|
} catch (error) {
|
|
3823
3879
|
if (!localError) {
|
|
3824
3880
|
throw error;
|
|
@@ -3834,6 +3890,34 @@ var AudioTranscriber = class {
|
|
|
3834
3890
|
}
|
|
3835
3891
|
return "";
|
|
3836
3892
|
}
|
|
3893
|
+
async transcribeOneWithOpenAiWithRetry(attachment) {
|
|
3894
|
+
let attempt = 0;
|
|
3895
|
+
while (true) {
|
|
3896
|
+
try {
|
|
3897
|
+
return await this.transcribeOneWithOpenAi(attachment);
|
|
3898
|
+
} catch (error) {
|
|
3899
|
+
if (!isRetryableOpenAiError(error) || attempt >= this.maxRetries) {
|
|
3900
|
+
throw error;
|
|
3901
|
+
}
|
|
3902
|
+
attempt += 1;
|
|
3903
|
+
await sleep2(this.retryDelayMs * attempt);
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3906
|
+
}
|
|
3907
|
+
async transcribeOneWithLocalWhisperWithRetry(attachment) {
|
|
3908
|
+
let attempt = 0;
|
|
3909
|
+
while (true) {
|
|
3910
|
+
try {
|
|
3911
|
+
return await this.transcribeOneWithLocalWhisper(attachment);
|
|
3912
|
+
} catch (error) {
|
|
3913
|
+
if (attempt >= this.maxRetries) {
|
|
3914
|
+
throw error;
|
|
3915
|
+
}
|
|
3916
|
+
attempt += 1;
|
|
3917
|
+
await sleep2(this.retryDelayMs * attempt);
|
|
3918
|
+
}
|
|
3919
|
+
}
|
|
3920
|
+
}
|
|
3837
3921
|
async transcribeOneWithOpenAi(attachment) {
|
|
3838
3922
|
if (!this.apiKey) {
|
|
3839
3923
|
return "";
|
|
@@ -3866,7 +3950,7 @@ var AudioTranscriber = class {
|
|
|
3866
3950
|
const payload = await response.json().catch(() => ({}));
|
|
3867
3951
|
if (!response.ok) {
|
|
3868
3952
|
const message = typeof payload?.error?.message === "string" ? payload.error.message : `HTTP ${response.status} ${response.statusText}`;
|
|
3869
|
-
throw new
|
|
3953
|
+
throw new OpenAiTranscriptionHttpError(response.status, `Audio transcription failed for ${attachment.name}: ${message}`);
|
|
3870
3954
|
}
|
|
3871
3955
|
const text = typeof payload.text === "string" ? payload.text.trim() : "";
|
|
3872
3956
|
return this.normalizeTranscriptText(text);
|
|
@@ -3911,12 +3995,38 @@ function buildLocalWhisperCommand(template, inputPath) {
|
|
|
3911
3995
|
function shellEscape(value) {
|
|
3912
3996
|
return `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
3913
3997
|
}
|
|
3998
|
+
function isRetryableOpenAiError(error) {
|
|
3999
|
+
if (error instanceof OpenAiTranscriptionHttpError) {
|
|
4000
|
+
return RETRYABLE_OPENAI_STATUS.has(error.status);
|
|
4001
|
+
}
|
|
4002
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
4003
|
+
return true;
|
|
4004
|
+
}
|
|
4005
|
+
return true;
|
|
4006
|
+
}
|
|
4007
|
+
async function sleep2(delayMs) {
|
|
4008
|
+
if (delayMs <= 0) {
|
|
4009
|
+
return;
|
|
4010
|
+
}
|
|
4011
|
+
await new Promise((resolve) => {
|
|
4012
|
+
const timer = setTimeout(resolve, delayMs);
|
|
4013
|
+
timer.unref?.();
|
|
4014
|
+
});
|
|
4015
|
+
}
|
|
3914
4016
|
function formatError3(error) {
|
|
3915
4017
|
if (error instanceof Error) {
|
|
3916
4018
|
return error.message;
|
|
3917
4019
|
}
|
|
3918
4020
|
return String(error);
|
|
3919
4021
|
}
|
|
4022
|
+
var OpenAiTranscriptionHttpError = class extends Error {
|
|
4023
|
+
status;
|
|
4024
|
+
constructor(status, message) {
|
|
4025
|
+
super(message);
|
|
4026
|
+
this.name = "OpenAiTranscriptionHttpError";
|
|
4027
|
+
this.status = status;
|
|
4028
|
+
}
|
|
4029
|
+
};
|
|
3920
4030
|
|
|
3921
4031
|
// src/compat/cli-compat-recorder.ts
|
|
3922
4032
|
var import_node_fs6 = __toESM(require("fs"));
|
|
@@ -4814,6 +4924,9 @@ var Orchestrator = class {
|
|
|
4814
4924
|
audioTranscribeModel: "gpt-4o-mini-transcribe",
|
|
4815
4925
|
audioTranscribeTimeoutMs: 12e4,
|
|
4816
4926
|
audioTranscribeMaxChars: 6e3,
|
|
4927
|
+
audioTranscribeMaxRetries: 1,
|
|
4928
|
+
audioTranscribeRetryDelayMs: 800,
|
|
4929
|
+
audioTranscribeMaxBytes: 26214400,
|
|
4817
4930
|
audioLocalWhisperCommand: null,
|
|
4818
4931
|
audioLocalWhisperTimeoutMs: 18e4,
|
|
4819
4932
|
recordPath: null
|
|
@@ -4825,6 +4938,8 @@ var Orchestrator = class {
|
|
|
4825
4938
|
model: this.cliCompat.audioTranscribeModel,
|
|
4826
4939
|
timeoutMs: this.cliCompat.audioTranscribeTimeoutMs,
|
|
4827
4940
|
maxChars: this.cliCompat.audioTranscribeMaxChars,
|
|
4941
|
+
maxRetries: this.cliCompat.audioTranscribeMaxRetries,
|
|
4942
|
+
retryDelayMs: this.cliCompat.audioTranscribeRetryDelayMs,
|
|
4828
4943
|
localWhisperCommand: this.cliCompat.audioLocalWhisperCommand,
|
|
4829
4944
|
localWhisperTimeoutMs: this.cliCompat.audioLocalWhisperTimeoutMs
|
|
4830
4945
|
});
|
|
@@ -5661,35 +5776,73 @@ var Orchestrator = class {
|
|
|
5661
5776
|
if (!this.audioTranscriber.isEnabled()) {
|
|
5662
5777
|
return [];
|
|
5663
5778
|
}
|
|
5664
|
-
const
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
}));
|
|
5669
|
-
if (audioAttachments.length === 0) {
|
|
5779
|
+
const rawAudioAttachments = message.attachments.filter(
|
|
5780
|
+
(attachment) => attachment.kind === "audio" && Boolean(attachment.localPath)
|
|
5781
|
+
);
|
|
5782
|
+
if (rawAudioAttachments.length === 0) {
|
|
5670
5783
|
return [];
|
|
5671
5784
|
}
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5785
|
+
const maxBytes = this.cliCompat.audioTranscribeMaxBytes;
|
|
5786
|
+
const audioAttachments = [];
|
|
5787
|
+
let skippedTooLarge = 0;
|
|
5788
|
+
for (const attachment of rawAudioAttachments) {
|
|
5789
|
+
const localPath = attachment.localPath;
|
|
5790
|
+
const sizeBytes = await this.resolveAudioAttachmentSizeBytes(attachment.sizeBytes, localPath);
|
|
5791
|
+
if (sizeBytes !== null && sizeBytes > maxBytes) {
|
|
5792
|
+
skippedTooLarge += 1;
|
|
5793
|
+
this.logger.warn("Skip audio transcription for oversized attachment", {
|
|
5676
5794
|
requestId,
|
|
5677
5795
|
sessionKey,
|
|
5678
|
-
|
|
5679
|
-
|
|
5796
|
+
name: attachment.name,
|
|
5797
|
+
sizeBytes,
|
|
5798
|
+
maxBytes
|
|
5680
5799
|
});
|
|
5800
|
+
continue;
|
|
5681
5801
|
}
|
|
5802
|
+
audioAttachments.push({
|
|
5803
|
+
name: attachment.name,
|
|
5804
|
+
mimeType: attachment.mimeType,
|
|
5805
|
+
localPath
|
|
5806
|
+
});
|
|
5807
|
+
}
|
|
5808
|
+
if (audioAttachments.length === 0) {
|
|
5809
|
+
return [];
|
|
5810
|
+
}
|
|
5811
|
+
const startedAt = Date.now();
|
|
5812
|
+
try {
|
|
5813
|
+
const transcripts = await this.audioTranscriber.transcribeMany(audioAttachments);
|
|
5814
|
+
this.logger.info("Audio transcription completed", {
|
|
5815
|
+
requestId,
|
|
5816
|
+
sessionKey,
|
|
5817
|
+
attachmentCount: audioAttachments.length,
|
|
5818
|
+
transcriptCount: transcripts.length,
|
|
5819
|
+
skippedTooLarge,
|
|
5820
|
+
durationMs: Date.now() - startedAt
|
|
5821
|
+
});
|
|
5682
5822
|
return transcripts;
|
|
5683
5823
|
} catch (error) {
|
|
5684
5824
|
this.logger.warn("Audio transcription failed, continuing without transcripts", {
|
|
5685
5825
|
requestId,
|
|
5686
5826
|
sessionKey,
|
|
5687
5827
|
attachmentCount: audioAttachments.length,
|
|
5828
|
+
skippedTooLarge,
|
|
5829
|
+
durationMs: Date.now() - startedAt,
|
|
5688
5830
|
error: formatError4(error)
|
|
5689
5831
|
});
|
|
5690
5832
|
return [];
|
|
5691
5833
|
}
|
|
5692
5834
|
}
|
|
5835
|
+
async resolveAudioAttachmentSizeBytes(sizeBytes, localPath) {
|
|
5836
|
+
if (sizeBytes !== null) {
|
|
5837
|
+
return sizeBytes;
|
|
5838
|
+
}
|
|
5839
|
+
try {
|
|
5840
|
+
const stats = await import_promises5.default.stat(localPath);
|
|
5841
|
+
return stats.size;
|
|
5842
|
+
} catch {
|
|
5843
|
+
return null;
|
|
5844
|
+
}
|
|
5845
|
+
}
|
|
5693
5846
|
buildExecutionPrompt(prompt, message, audioTranscripts) {
|
|
5694
5847
|
if (message.attachments.length === 0 && audioTranscripts.length === 0) {
|
|
5695
5848
|
return prompt;
|
|
@@ -6590,6 +6743,9 @@ var configSchema = import_zod.z.object({
|
|
|
6590
6743
|
CLI_COMPAT_AUDIO_TRANSCRIBE_MODEL: import_zod.z.string().default("gpt-4o-mini-transcribe"),
|
|
6591
6744
|
CLI_COMPAT_AUDIO_TRANSCRIBE_TIMEOUT_MS: import_zod.z.string().default("120000").transform((v) => Number.parseInt(v, 10)).pipe(import_zod.z.number().int().positive()),
|
|
6592
6745
|
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_CHARS: import_zod.z.string().default("6000").transform((v) => Number.parseInt(v, 10)).pipe(import_zod.z.number().int().positive()),
|
|
6746
|
+
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_RETRIES: import_zod.z.string().default("1").transform((v) => Number.parseInt(v, 10)).pipe(import_zod.z.number().int().min(0).max(10)),
|
|
6747
|
+
CLI_COMPAT_AUDIO_TRANSCRIBE_RETRY_DELAY_MS: import_zod.z.string().default("800").transform((v) => Number.parseInt(v, 10)).pipe(import_zod.z.number().int().nonnegative()),
|
|
6748
|
+
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_BYTES: import_zod.z.string().default("26214400").transform((v) => Number.parseInt(v, 10)).pipe(import_zod.z.number().int().positive()),
|
|
6593
6749
|
CLI_COMPAT_AUDIO_LOCAL_WHISPER_COMMAND: import_zod.z.string().default(""),
|
|
6594
6750
|
CLI_COMPAT_AUDIO_LOCAL_WHISPER_TIMEOUT_MS: import_zod.z.string().default("180000").transform((v) => Number.parseInt(v, 10)).pipe(import_zod.z.number().int().positive()),
|
|
6595
6751
|
CLI_COMPAT_RECORD_PATH: import_zod.z.string().default(""),
|
|
@@ -6656,6 +6812,9 @@ var configSchema = import_zod.z.object({
|
|
|
6656
6812
|
audioTranscribeModel: v.CLI_COMPAT_AUDIO_TRANSCRIBE_MODEL.trim() || "gpt-4o-mini-transcribe",
|
|
6657
6813
|
audioTranscribeTimeoutMs: v.CLI_COMPAT_AUDIO_TRANSCRIBE_TIMEOUT_MS,
|
|
6658
6814
|
audioTranscribeMaxChars: v.CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_CHARS,
|
|
6815
|
+
audioTranscribeMaxRetries: v.CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_RETRIES,
|
|
6816
|
+
audioTranscribeRetryDelayMs: v.CLI_COMPAT_AUDIO_TRANSCRIBE_RETRY_DELAY_MS,
|
|
6817
|
+
audioTranscribeMaxBytes: v.CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_BYTES,
|
|
6659
6818
|
audioLocalWhisperCommand: v.CLI_COMPAT_AUDIO_LOCAL_WHISPER_COMMAND.trim() ? v.CLI_COMPAT_AUDIO_LOCAL_WHISPER_COMMAND.trim() : null,
|
|
6660
6819
|
audioLocalWhisperTimeoutMs: v.CLI_COMPAT_AUDIO_LOCAL_WHISPER_TIMEOUT_MS,
|
|
6661
6820
|
recordPath: v.CLI_COMPAT_RECORD_PATH.trim() ? import_node_path12.default.resolve(v.CLI_COMPAT_RECORD_PATH) : null
|
|
@@ -6903,6 +7062,9 @@ var CONFIG_SNAPSHOT_ENV_KEYS = [
|
|
|
6903
7062
|
"CLI_COMPAT_AUDIO_TRANSCRIBE_MODEL",
|
|
6904
7063
|
"CLI_COMPAT_AUDIO_TRANSCRIBE_TIMEOUT_MS",
|
|
6905
7064
|
"CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_CHARS",
|
|
7065
|
+
"CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_RETRIES",
|
|
7066
|
+
"CLI_COMPAT_AUDIO_TRANSCRIBE_RETRY_DELAY_MS",
|
|
7067
|
+
"CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_BYTES",
|
|
6906
7068
|
"CLI_COMPAT_AUDIO_LOCAL_WHISPER_COMMAND",
|
|
6907
7069
|
"CLI_COMPAT_AUDIO_LOCAL_WHISPER_TIMEOUT_MS",
|
|
6908
7070
|
"CLI_COMPAT_RECORD_PATH",
|
|
@@ -6979,6 +7141,16 @@ var envSnapshotSchema = import_zod2.z.object({
|
|
|
6979
7141
|
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_CHARS: integerStringSchema("CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_CHARS", 1).default(
|
|
6980
7142
|
"6000"
|
|
6981
7143
|
),
|
|
7144
|
+
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_RETRIES: integerStringSchema("CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_RETRIES", 0, 10).default(
|
|
7145
|
+
"1"
|
|
7146
|
+
),
|
|
7147
|
+
CLI_COMPAT_AUDIO_TRANSCRIBE_RETRY_DELAY_MS: integerStringSchema(
|
|
7148
|
+
"CLI_COMPAT_AUDIO_TRANSCRIBE_RETRY_DELAY_MS",
|
|
7149
|
+
0
|
|
7150
|
+
).default("800"),
|
|
7151
|
+
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_BYTES: integerStringSchema("CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_BYTES", 1).default(
|
|
7152
|
+
"26214400"
|
|
7153
|
+
),
|
|
6982
7154
|
CLI_COMPAT_AUDIO_LOCAL_WHISPER_COMMAND: import_zod2.z.string().default(""),
|
|
6983
7155
|
CLI_COMPAT_AUDIO_LOCAL_WHISPER_TIMEOUT_MS: integerStringSchema(
|
|
6984
7156
|
"CLI_COMPAT_AUDIO_LOCAL_WHISPER_TIMEOUT_MS",
|
|
@@ -7178,6 +7350,9 @@ function buildSnapshotEnv(config) {
|
|
|
7178
7350
|
CLI_COMPAT_AUDIO_TRANSCRIBE_MODEL: config.cliCompat.audioTranscribeModel,
|
|
7179
7351
|
CLI_COMPAT_AUDIO_TRANSCRIBE_TIMEOUT_MS: String(config.cliCompat.audioTranscribeTimeoutMs),
|
|
7180
7352
|
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_CHARS: String(config.cliCompat.audioTranscribeMaxChars),
|
|
7353
|
+
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_RETRIES: String(config.cliCompat.audioTranscribeMaxRetries),
|
|
7354
|
+
CLI_COMPAT_AUDIO_TRANSCRIBE_RETRY_DELAY_MS: String(config.cliCompat.audioTranscribeRetryDelayMs),
|
|
7355
|
+
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_BYTES: String(config.cliCompat.audioTranscribeMaxBytes),
|
|
7181
7356
|
CLI_COMPAT_AUDIO_LOCAL_WHISPER_COMMAND: config.cliCompat.audioLocalWhisperCommand ?? "",
|
|
7182
7357
|
CLI_COMPAT_AUDIO_LOCAL_WHISPER_TIMEOUT_MS: String(config.cliCompat.audioLocalWhisperTimeoutMs),
|
|
7183
7358
|
CLI_COMPAT_RECORD_PATH: config.cliCompat.recordPath ?? "",
|