charness 3.2.0 → 3.3.1
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 +3 -6
- package/DEVELOPMENT.md +15 -0
- package/README.md +111 -38
- package/SETUP.md +121 -16
- package/dist/adapters/adapterEventRouting.d.ts +2 -1
- package/dist/adapters/adapterEventRouting.d.ts.map +1 -1
- package/dist/adapters/adapterEventRouting.js +3 -0
- package/dist/adapters/adapterEventRouting.js.map +1 -1
- package/dist/adapters/adapterNames.d.ts +13 -0
- package/dist/adapters/adapterNames.d.ts.map +1 -1
- package/dist/adapters/adapterNames.js +16 -0
- package/dist/adapters/adapterNames.js.map +1 -1
- package/dist/adapters/backendUnavailableError.d.ts +11 -0
- package/dist/adapters/backendUnavailableError.d.ts.map +1 -0
- package/dist/adapters/backendUnavailableError.js +19 -0
- package/dist/adapters/backendUnavailableError.js.map +1 -0
- package/dist/adapters/claudeCliAdapter.d.ts +29 -6
- package/dist/adapters/claudeCliAdapter.d.ts.map +1 -1
- package/dist/adapters/claudeCliAdapter.js +70 -16
- package/dist/adapters/claudeCliAdapter.js.map +1 -1
- package/dist/adapters/claudeJsonStreamAdapter.d.ts +36 -3
- package/dist/adapters/claudeJsonStreamAdapter.d.ts.map +1 -1
- package/dist/adapters/claudeJsonStreamAdapter.js +93 -30
- package/dist/adapters/claudeJsonStreamAdapter.js.map +1 -1
- package/dist/adapters/createAdapter.d.ts +3 -14
- package/dist/adapters/createAdapter.d.ts.map +1 -1
- package/dist/adapters/createAdapter.js +9 -19
- package/dist/adapters/createAdapter.js.map +1 -1
- package/dist/adapters/openCodeAdapter.d.ts +140 -12
- package/dist/adapters/openCodeAdapter.d.ts.map +1 -1
- package/dist/adapters/openCodeAdapter.js +385 -119
- package/dist/adapters/openCodeAdapter.js.map +1 -1
- package/dist/apiErrorRetry.d.ts +70 -6
- package/dist/apiErrorRetry.d.ts.map +1 -1
- package/dist/apiErrorRetry.js +312 -34
- package/dist/apiErrorRetry.js.map +1 -1
- package/dist/apiRetryKick.d.ts +26 -1
- package/dist/apiRetryKick.d.ts.map +1 -1
- package/dist/apiRetryKick.js +41 -2
- package/dist/apiRetryKick.js.map +1 -1
- package/dist/bot.d.ts +2 -1
- package/dist/bot.d.ts.map +1 -1
- package/dist/bot.js +736 -184
- package/dist/bot.js.map +1 -1
- package/dist/cli/claudeProfiles.d.ts +1 -1
- package/dist/cli/claudeProfiles.js +1 -1
- package/dist/cli/hot.d.ts +7 -1
- package/dist/cli/hot.d.ts.map +1 -1
- package/dist/cli/hot.js +29 -3
- package/dist/cli/hot.js.map +1 -1
- package/dist/configDirFile.d.ts +73 -0
- package/dist/configDirFile.d.ts.map +1 -0
- package/dist/configDirFile.js +216 -0
- package/dist/configDirFile.js.map +1 -0
- package/dist/connectors/telegram/commands/autoContinueLimits.d.ts +2 -2
- package/dist/connectors/telegram/commands/autoContinueLimits.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/autoContinueLimits.js +4 -4
- package/dist/connectors/telegram/commands/autoContinueLimits.js.map +1 -1
- package/dist/connectors/telegram/commands/backendSwitch.d.ts +25 -0
- package/dist/connectors/telegram/commands/backendSwitch.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/backendSwitch.js +104 -0
- package/dist/connectors/telegram/commands/backendSwitch.js.map +1 -0
- package/dist/connectors/telegram/commands/callbackMessage.d.ts +12 -0
- package/dist/connectors/telegram/commands/callbackMessage.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/callbackMessage.js +24 -0
- package/dist/connectors/telegram/commands/callbackMessage.js.map +1 -1
- package/dist/connectors/telegram/commands/callbackToast.d.ts +36 -0
- package/dist/connectors/telegram/commands/callbackToast.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/callbackToast.js +83 -0
- package/dist/connectors/telegram/commands/callbackToast.js.map +1 -0
- package/dist/connectors/telegram/commands/claudeAccounts.d.ts +18 -0
- package/dist/connectors/telegram/commands/claudeAccounts.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/claudeAccounts.js +220 -66
- package/dist/connectors/telegram/commands/claudeAccounts.js.map +1 -1
- package/dist/connectors/telegram/commands/displayModes.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/displayModes.js +4 -2
- package/dist/connectors/telegram/commands/displayModes.js.map +1 -1
- package/dist/connectors/telegram/commands/fallbackChain.d.ts +5 -8
- package/dist/connectors/telegram/commands/fallbackChain.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/fallbackChain.js +183 -193
- package/dist/connectors/telegram/commands/fallbackChain.js.map +1 -1
- package/dist/connectors/telegram/commands/limitsBoard.d.ts +40 -0
- package/dist/connectors/telegram/commands/limitsBoard.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/limitsBoard.js +281 -0
- package/dist/connectors/telegram/commands/limitsBoard.js.map +1 -0
- package/dist/connectors/telegram/commands/modelPage.d.ts +130 -0
- package/dist/connectors/telegram/commands/modelPage.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/modelPage.js +120 -0
- package/dist/connectors/telegram/commands/modelPage.js.map +1 -0
- package/dist/connectors/telegram/commands/modelProviders.d.ts +9 -1
- package/dist/connectors/telegram/commands/modelProviders.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/modelProviders.js +203 -111
- package/dist/connectors/telegram/commands/modelProviders.js.map +1 -1
- package/dist/connectors/telegram/commands/stt.d.ts +32 -0
- package/dist/connectors/telegram/commands/stt.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/stt.js +460 -0
- package/dist/connectors/telegram/commands/stt.js.map +1 -0
- package/dist/effortLevels.d.ts +57 -7
- package/dist/effortLevels.d.ts.map +1 -1
- package/dist/effortLevels.js +65 -9
- package/dist/effortLevels.js.map +1 -1
- package/dist/i18n/de.d.ts.map +1 -1
- package/dist/i18n/de.js +160 -17
- package/dist/i18n/de.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +160 -17
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/es.js +160 -17
- package/dist/i18n/es.js.map +1 -1
- package/dist/i18n/fr.d.ts.map +1 -1
- package/dist/i18n/fr.js +160 -17
- package/dist/i18n/fr.js.map +1 -1
- package/dist/i18n/hi.d.ts.map +1 -1
- package/dist/i18n/hi.js +160 -17
- package/dist/i18n/hi.js.map +1 -1
- package/dist/i18n/ja.d.ts.map +1 -1
- package/dist/i18n/ja.js +160 -17
- package/dist/i18n/ja.js.map +1 -1
- package/dist/i18n/ka.d.ts.map +1 -1
- package/dist/i18n/ka.js +160 -17
- package/dist/i18n/ka.js.map +1 -1
- package/dist/i18n/pt.d.ts.map +1 -1
- package/dist/i18n/pt.js +160 -17
- package/dist/i18n/pt.js.map +1 -1
- package/dist/i18n/ru.d.ts.map +1 -1
- package/dist/i18n/ru.js +160 -17
- package/dist/i18n/ru.js.map +1 -1
- package/dist/i18n/uk.d.ts.map +1 -1
- package/dist/i18n/uk.js +160 -17
- package/dist/i18n/uk.js.map +1 -1
- package/dist/i18n/uz.d.ts.map +1 -1
- package/dist/i18n/uz.js +160 -17
- package/dist/i18n/uz.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +160 -17
- package/dist/i18n/zh.js.map +1 -1
- package/dist/installManager.d.ts +20 -4
- package/dist/installManager.d.ts.map +1 -1
- package/dist/installManager.js +82 -14
- package/dist/installManager.js.map +1 -1
- package/dist/instanceSettings.d.ts +52 -0
- package/dist/instanceSettings.d.ts.map +1 -0
- package/dist/instanceSettings.js +136 -0
- package/dist/instanceSettings.js.map +1 -0
- package/dist/pinnedStatus.d.ts +7 -1
- package/dist/pinnedStatus.d.ts.map +1 -1
- package/dist/pinnedStatus.js +1 -1
- package/dist/pinnedStatus.js.map +1 -1
- package/dist/requests/requestLedger.d.ts +8 -0
- package/dist/requests/requestLedger.d.ts.map +1 -1
- package/dist/requests/requestLedger.js +19 -1
- package/dist/requests/requestLedger.js.map +1 -1
- package/dist/scheduler/mcpSurface.js +4 -4
- package/dist/scheduler/mcpSurface.js.map +1 -1
- package/dist/shutdown.d.ts +14 -0
- package/dist/shutdown.d.ts.map +1 -1
- package/dist/shutdown.js +16 -0
- package/dist/shutdown.js.map +1 -1
- package/dist/state.d.ts +54 -2
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +62 -1
- package/dist/state.js.map +1 -1
- package/dist/stt/sttAutoInstall.d.ts +39 -0
- package/dist/stt/sttAutoInstall.d.ts.map +1 -0
- package/dist/stt/sttAutoInstall.js +158 -0
- package/dist/stt/sttAutoInstall.js.map +1 -0
- package/dist/stt/sttChildEnv.d.ts +11 -0
- package/dist/stt/sttChildEnv.d.ts.map +1 -0
- package/dist/stt/sttChildEnv.js +30 -0
- package/dist/stt/sttChildEnv.js.map +1 -0
- package/dist/stt/sttConfigEdit.d.ts +71 -0
- package/dist/stt/sttConfigEdit.d.ts.map +1 -0
- package/dist/stt/sttConfigEdit.js +144 -0
- package/dist/stt/sttConfigEdit.js.map +1 -0
- package/dist/stt/sttInstall.d.ts +147 -0
- package/dist/stt/sttInstall.d.ts.map +1 -0
- package/dist/stt/sttInstall.js +491 -0
- package/dist/stt/sttInstall.js.map +1 -0
- package/dist/stt/sttInstallEntry.d.ts +2 -0
- package/dist/stt/sttInstallEntry.d.ts.map +1 -0
- package/dist/stt/sttInstallEntry.js +31 -0
- package/dist/stt/sttInstallEntry.js.map +1 -0
- package/dist/stt/sttInstallReporter.d.ts +45 -0
- package/dist/stt/sttInstallReporter.d.ts.map +1 -0
- package/dist/stt/sttInstallReporter.js +57 -0
- package/dist/stt/sttInstallReporter.js.map +1 -0
- package/dist/stt/sttRuntime.d.ts +35 -0
- package/dist/stt/sttRuntime.d.ts.map +1 -0
- package/dist/stt/sttRuntime.js +73 -0
- package/dist/stt/sttRuntime.js.map +1 -0
- package/dist/stt/sttScreenPlan.d.ts +193 -0
- package/dist/stt/sttScreenPlan.d.ts.map +1 -0
- package/dist/stt/sttScreenPlan.js +541 -0
- package/dist/stt/sttScreenPlan.js.map +1 -0
- package/dist/stt/sttSettings.d.ts +201 -0
- package/dist/stt/sttSettings.d.ts.map +1 -0
- package/dist/stt/sttSettings.js +387 -0
- package/dist/stt/sttSettings.js.map +1 -0
- package/dist/stt/sttSidecarOwner.d.ts +115 -0
- package/dist/stt/sttSidecarOwner.d.ts.map +1 -0
- package/dist/stt/sttSidecarOwner.js +475 -0
- package/dist/stt/sttSidecarOwner.js.map +1 -0
- package/dist/stt/transcribeChain.d.ts +36 -0
- package/dist/stt/transcribeChain.d.ts.map +1 -0
- package/dist/stt/transcribeChain.js +42 -0
- package/dist/stt/transcribeChain.js.map +1 -0
- package/dist/types.d.ts +77 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/adapterSwitchSessionIds.d.ts +32 -0
- package/dist/utils/adapterSwitchSessionIds.d.ts.map +1 -0
- package/dist/utils/adapterSwitchSessionIds.js +44 -0
- package/dist/utils/adapterSwitchSessionIds.js.map +1 -0
- package/dist/utils/backendSwitchPlan.d.ts +63 -0
- package/dist/utils/backendSwitchPlan.d.ts.map +1 -0
- package/dist/utils/backendSwitchPlan.js +73 -0
- package/dist/utils/backendSwitchPlan.js.map +1 -0
- package/dist/utils/claudeAccountPickerPlan.d.ts +12 -1
- package/dist/utils/claudeAccountPickerPlan.d.ts.map +1 -1
- package/dist/utils/claudeAccountPickerPlan.js +20 -1
- package/dist/utils/claudeAccountPickerPlan.js.map +1 -1
- package/dist/utils/claudeTranscriptContent.d.ts +24 -0
- package/dist/utils/claudeTranscriptContent.d.ts.map +1 -0
- package/dist/utils/claudeTranscriptContent.js +107 -0
- package/dist/utils/claudeTranscriptContent.js.map +1 -0
- package/dist/utils/claudeUsage.d.ts +47 -8
- package/dist/utils/claudeUsage.d.ts.map +1 -1
- package/dist/utils/claudeUsage.js +76 -14
- package/dist/utils/claudeUsage.js.map +1 -1
- package/dist/utils/claudeUsageRefresher.d.ts +8 -1
- package/dist/utils/claudeUsageRefresher.d.ts.map +1 -1
- package/dist/utils/claudeUsageRefresher.js +9 -4
- package/dist/utils/claudeUsageRefresher.js.map +1 -1
- package/dist/utils/effortPickerPlan.d.ts +54 -0
- package/dist/utils/effortPickerPlan.d.ts.map +1 -0
- package/dist/utils/effortPickerPlan.js +56 -0
- package/dist/utils/effortPickerPlan.js.map +1 -0
- package/dist/utils/ensureSessionPlan.d.ts +20 -4
- package/dist/utils/ensureSessionPlan.d.ts.map +1 -1
- package/dist/utils/ensureSessionPlan.js +17 -4
- package/dist/utils/ensureSessionPlan.js.map +1 -1
- package/dist/utils/fallbackBridge.d.ts +6 -2
- package/dist/utils/fallbackBridge.d.ts.map +1 -1
- package/dist/utils/fallbackBridge.js +10 -3
- package/dist/utils/fallbackBridge.js.map +1 -1
- package/dist/utils/fallbackChain.d.ts +36 -0
- package/dist/utils/fallbackChain.d.ts.map +1 -1
- package/dist/utils/fallbackChain.js +65 -1
- package/dist/utils/fallbackChain.js.map +1 -1
- package/dist/utils/fallbackSwitchNotice.d.ts +41 -0
- package/dist/utils/fallbackSwitchNotice.d.ts.map +1 -0
- package/dist/utils/fallbackSwitchNotice.js +75 -0
- package/dist/utils/fallbackSwitchNotice.js.map +1 -0
- package/dist/utils/fileSendService.d.ts +33 -10
- package/dist/utils/fileSendService.d.ts.map +1 -1
- package/dist/utils/fileSendService.js +78 -27
- package/dist/utils/fileSendService.js.map +1 -1
- package/dist/utils/jsonStreamHost.d.ts +39 -0
- package/dist/utils/jsonStreamHost.d.ts.map +1 -1
- package/dist/utils/jsonStreamHost.js +60 -1
- package/dist/utils/jsonStreamHost.js.map +1 -1
- package/dist/utils/limitEpisodeRecovery.d.ts +16 -2
- package/dist/utils/limitEpisodeRecovery.d.ts.map +1 -1
- package/dist/utils/limitEpisodeRecovery.js +44 -3
- package/dist/utils/limitEpisodeRecovery.js.map +1 -1
- package/dist/utils/limitSettings.d.ts +25 -0
- package/dist/utils/limitSettings.d.ts.map +1 -0
- package/dist/utils/limitSettings.js +31 -0
- package/dist/utils/limitSettings.js.map +1 -0
- package/dist/utils/limitsBoardPlan.d.ts +52 -0
- package/dist/utils/limitsBoardPlan.d.ts.map +1 -0
- package/dist/utils/limitsBoardPlan.js +93 -0
- package/dist/utils/limitsBoardPlan.js.map +1 -0
- package/dist/utils/openCodeUsage.d.ts +93 -0
- package/dist/utils/openCodeUsage.d.ts.map +1 -0
- package/dist/utils/openCodeUsage.js +248 -0
- package/dist/utils/openCodeUsage.js.map +1 -0
- package/dist/utils/operatorSwitchPlan.d.ts +61 -0
- package/dist/utils/operatorSwitchPlan.d.ts.map +1 -0
- package/dist/utils/operatorSwitchPlan.js +32 -0
- package/dist/utils/operatorSwitchPlan.js.map +1 -0
- package/dist/utils/promptDelivery.d.ts +40 -0
- package/dist/utils/promptDelivery.d.ts.map +1 -1
- package/dist/utils/promptDelivery.js +31 -0
- package/dist/utils/promptDelivery.js.map +1 -1
- package/dist/utils/recvPreviewRedaction.d.ts +14 -4
- package/dist/utils/recvPreviewRedaction.d.ts.map +1 -1
- package/dist/utils/recvPreviewRedaction.js +19 -7
- package/dist/utils/recvPreviewRedaction.js.map +1 -1
- package/dist/utils/startupReadiness.d.ts +3 -3
- package/dist/utils/startupReadiness.d.ts.map +1 -1
- package/dist/utils/startupReadiness.js +2 -2
- package/dist/utils/startupReadiness.js.map +1 -1
- package/dist/utils/threadStatusReport.d.ts +3 -1
- package/dist/utils/threadStatusReport.d.ts.map +1 -1
- package/dist/utils/threadStatusReport.js +4 -3
- package/dist/utils/threadStatusReport.js.map +1 -1
- package/dist/utils/timezone.d.ts +23 -0
- package/dist/utils/timezone.d.ts.map +1 -1
- package/dist/utils/timezone.js +38 -0
- package/dist/utils/timezone.js.map +1 -1
- package/dist/utils/transcribeAudio.d.ts +25 -12
- package/dist/utils/transcribeAudio.d.ts.map +1 -1
- package/dist/utils/transcribeAudio.js +39 -21
- package/dist/utils/transcribeAudio.js.map +1 -1
- package/dist/utils/usageRefreshBudget.d.ts +9 -0
- package/dist/utils/usageRefreshBudget.d.ts.map +1 -0
- package/dist/utils/usageRefreshBudget.js +27 -0
- package/dist/utils/usageRefreshBudget.js.map +1 -0
- package/examples/.env.example +7 -3
- package/examples/docker-compose.yml +9 -7
- package/package.json +5 -4
- package/stt/gigaam_sidecar.py +800 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { type ConfigFileLoad, type ConfigValidation } from '../configDirFile';
|
|
2
|
+
import { type TranscriptionEndpoint } from '../utils/transcribeAudio';
|
|
3
|
+
/**
|
|
4
|
+
* @description The voice-recognition settings: ONE JSON file, `stt.json`, next to
|
|
5
|
+
* the instance's `.env`, holding the engine chain, the language, the local
|
|
6
|
+
* engine's knobs AND the API keys. `/stt` writes it; an operator may hand-edit
|
|
7
|
+
* it, and the next voice note sees the edit (the load is cached by file stamp).
|
|
8
|
+
*
|
|
9
|
+
* Validation is strict and all-or-nothing, like `jira.json`: a typo is an error
|
|
10
|
+
* that NAMES the field and never echoes a value (a key may sit next to it), and
|
|
11
|
+
* an invalid edit keeps the last good settings instead of silently dropping an
|
|
12
|
+
* engine.
|
|
13
|
+
*/
|
|
14
|
+
/** The file in the config dir. */
|
|
15
|
+
export declare const sttConfigFileName = "stt.json";
|
|
16
|
+
export declare const sttEngineKinds: readonly ["gigaam", "groq", "openai", "url"];
|
|
17
|
+
export type SttEngineKind = (typeof sttEngineKinds)[number];
|
|
18
|
+
/** The most engines one chain holds. */
|
|
19
|
+
export declare const sttEngineLimit = 6;
|
|
20
|
+
/** The worker counts `/stt` offers; a hand-edited value is clamped to the nearest one. */
|
|
21
|
+
export declare const sttGigaamWorkerChoices: readonly number[];
|
|
22
|
+
/** The shape of an engine's request budget: `baseSeconds + percentOfDuration % of the voice`. */
|
|
23
|
+
export interface SttTimeout {
|
|
24
|
+
baseSeconds: number;
|
|
25
|
+
percentOfDuration: number;
|
|
26
|
+
}
|
|
27
|
+
export declare const defaultSttTimeout: SttTimeout;
|
|
28
|
+
export declare const defaultGigaamIdleMinutes = 15;
|
|
29
|
+
export declare const defaultGigaamWorkers = 4;
|
|
30
|
+
/** Intra-op threads per worker; `workers × threads` should not exceed the CPU count. */
|
|
31
|
+
export declare const defaultGigaamThreads = 2;
|
|
32
|
+
/** The only language the local engine knows. */
|
|
33
|
+
export declare const gigaamLanguage = "ru";
|
|
34
|
+
/** @name SttEngineSetting @description One entry of the chain, as stored in `stt.json`. */
|
|
35
|
+
export interface SttEngineSetting {
|
|
36
|
+
/** Stable short id (`g`, `q1`, `u2`): `/stt` callback data carries it, so lowercase letters and digits only. */
|
|
37
|
+
id: string;
|
|
38
|
+
kind: SttEngineKind;
|
|
39
|
+
isDisabled?: boolean;
|
|
40
|
+
/** Absent → {@link defaultSttTimeout}. */
|
|
41
|
+
timeout?: SttTimeout;
|
|
42
|
+
/** `url` kind: the FULL transcription endpoint URL. */
|
|
43
|
+
url?: string;
|
|
44
|
+
/** `url` kind: the model name sent along (default `whisper-1`). */
|
|
45
|
+
model?: string;
|
|
46
|
+
/** `groq` / `openai` / `url`: never logged or echoed. */
|
|
47
|
+
apiKey?: string;
|
|
48
|
+
}
|
|
49
|
+
/** @name SttGigaamSettings @description The local engine's process knobs. */
|
|
50
|
+
export interface SttGigaamSettings {
|
|
51
|
+
/** The process exits after this many idle minutes; `0` = never. */
|
|
52
|
+
idleMinutes: number;
|
|
53
|
+
/** Chunks recognised in parallel; one of {@link sttGigaamWorkerChoices}. */
|
|
54
|
+
workers: number;
|
|
55
|
+
/** Intra-op threads per worker; a hand-edit-only knob, absent → {@link defaultGigaamThreads}. */
|
|
56
|
+
threads?: number;
|
|
57
|
+
}
|
|
58
|
+
/** @name SttConfigFile @description The whole of `stt.json`. */
|
|
59
|
+
export interface SttConfigFile {
|
|
60
|
+
/** Ordered: the first available engine is tried first. */
|
|
61
|
+
engines: SttEngineSetting[];
|
|
62
|
+
/** ISO-639-1 (`ru`), or `null` = the engine detects the language. */
|
|
63
|
+
language: string | null;
|
|
64
|
+
gigaam: SttGigaamSettings;
|
|
65
|
+
}
|
|
66
|
+
export type SttConfigResult = ConfigValidation<SttConfigFile>;
|
|
67
|
+
/** @description The settings of an instance that has no `stt.json`: no engines, auto language. */
|
|
68
|
+
export declare function createEmptySttConfig(): SttConfigFile;
|
|
69
|
+
/** @description The worker count nearest to `workers` among {@link sttGigaamWorkerChoices} (a tie goes to the smaller). */
|
|
70
|
+
export declare function clampSttWorkers(workers: number): number;
|
|
71
|
+
/** @description `config` with the worker count clamped to a choice `/stt` offers. */
|
|
72
|
+
export declare function normaliseSttConfig(config: SttConfigFile): SttConfigFile;
|
|
73
|
+
/**
|
|
74
|
+
* @description Validate a parsed `stt.json` object. Every error names its field
|
|
75
|
+
* (`stt.json engines.1.timeout.baseSeconds: …`) and never carries a value.
|
|
76
|
+
*/
|
|
77
|
+
export declare function validateSttConfig(parsedJson: object): SttConfigResult;
|
|
78
|
+
/**
|
|
79
|
+
* @description Where `stt.json` lives: beside the instance's REAL env file (see {@link getConfigDirFilePath} for
|
|
80
|
+
* the rules — a symlinked `.env` is resolved, so the file that holds API keys lands beside the real one).
|
|
81
|
+
*/
|
|
82
|
+
export declare function getSttConfigPath(env?: NodeJS.ProcessEnv, homeDir?: string): string;
|
|
83
|
+
/**
|
|
84
|
+
* @description What the file holds right now. `invalid` keeps the LAST GOOD
|
|
85
|
+
* settings (`null` when the file was never valid in this process), so a bad hand
|
|
86
|
+
* edit never takes voice down.
|
|
87
|
+
*/
|
|
88
|
+
export type SttConfigLoad = ConfigFileLoad<SttConfigFile>;
|
|
89
|
+
/**
|
|
90
|
+
* @description Read and validate `stt.json`, cached by the file's stamp
|
|
91
|
+
* (mtime, size, inode) so a per-voice call costs one `stat`. A missing file is
|
|
92
|
+
* the empty settings; an unreadable or invalid one keeps the last good settings.
|
|
93
|
+
*/
|
|
94
|
+
export declare const loadSttConfig: (filePath: string) => ConfigFileLoad<SttConfigFile>;
|
|
95
|
+
/** @description Forget every cached load — for tests, which swap files under one path. */
|
|
96
|
+
export declare const resetSttConfigCache: () => void;
|
|
97
|
+
/**
|
|
98
|
+
* @description Write `config` to `filePath`: validated first (a caller that builds
|
|
99
|
+
* an invalid file has a bug), then written mode 0600 through a temp file and a
|
|
100
|
+
* rename, so a reader never sees half a file.
|
|
101
|
+
*/
|
|
102
|
+
export declare function saveSttConfig(filePath: string, config: SttConfigFile): void;
|
|
103
|
+
/** @name SttMigrationResult @description What {@link migrateLegacySttKeys} did. */
|
|
104
|
+
export type SttMigrationResult = {
|
|
105
|
+
status: 'noKeys';
|
|
106
|
+
} | {
|
|
107
|
+
status: 'fileExists';
|
|
108
|
+
} | {
|
|
109
|
+
status: 'migrated';
|
|
110
|
+
engineNames: string[];
|
|
111
|
+
} | {
|
|
112
|
+
status: 'writeFailed';
|
|
113
|
+
error: string;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* @description The ONE-TIME migration of the pre-`stt.json` setup: with no file
|
|
117
|
+
* yet and `GROQ_API_KEY` / `OPENAI_API_KEY` set, write `stt.json` with those
|
|
118
|
+
* engines (Groq first) and their keys. From then on the env keys are ignored;
|
|
119
|
+
* a process that still sees one says so once. Never overwrites an existing file.
|
|
120
|
+
*/
|
|
121
|
+
export declare function migrateLegacySttKeys(filePath: string, env?: NodeJS.ProcessEnv, writeLine?: (text: string) => void): SttMigrationResult;
|
|
122
|
+
/**
|
|
123
|
+
* @description `/stt`'s engine id for a new engine of `kind`: `g` for the local
|
|
124
|
+
* one, else the kind's letter plus the smallest number not taken (`q1`, `o2`, `u1`).
|
|
125
|
+
*/
|
|
126
|
+
export declare function createSttEngineId(kind: SttEngineKind, takenIds: ReadonlySet<string>): string;
|
|
127
|
+
/** @description What the resolver needs to know about the host (the local engine's lifecycle). */
|
|
128
|
+
export interface SttFacts {
|
|
129
|
+
isGigaamInstalled: boolean;
|
|
130
|
+
isGigaamInstalling: boolean;
|
|
131
|
+
/** The spawn-storm guard marked the local engine unhealthy. */
|
|
132
|
+
isGigaamUnhealthy: boolean;
|
|
133
|
+
/** The sidecar has a long-lived process to die with (supervisor or bot); without one it is never started. */
|
|
134
|
+
hasOwnerContext: boolean;
|
|
135
|
+
}
|
|
136
|
+
/** @description Hooks the resolver cannot know: how the local engine's endpoint is produced at call time. */
|
|
137
|
+
export interface SttResolveOptions {
|
|
138
|
+
/** Starts the sidecar if needed and returns its endpoint; absent → the local engine is unavailable. */
|
|
139
|
+
getGigaamEndpoint?: () => Promise<TranscriptionEndpoint>;
|
|
140
|
+
}
|
|
141
|
+
export type SttUnavailableReason = 'disabled' | 'notInstalled' | 'installing' | 'unhealthy' | 'languageNotSupported' | 'noOwnerContext' | 'missingKey' | 'missingUrl';
|
|
142
|
+
/** An engine that will be tried, with its endpoint produced lazily. */
|
|
143
|
+
export interface ResolvedSttEngine {
|
|
144
|
+
id: string;
|
|
145
|
+
kind: SttEngineKind;
|
|
146
|
+
/** What logs call it: the kind, or `url:<host>` for a custom server. */
|
|
147
|
+
name: string;
|
|
148
|
+
timeout: SttTimeout;
|
|
149
|
+
/** Static engines answer at once; the local engine starts its process here and may reject. */
|
|
150
|
+
getEndpoint: () => Promise<TranscriptionEndpoint>;
|
|
151
|
+
}
|
|
152
|
+
export interface UnavailableSttEngine {
|
|
153
|
+
id: string;
|
|
154
|
+
kind: SttEngineKind;
|
|
155
|
+
reason: SttUnavailableReason;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Where the effective settings came from: the valid file, none (no file),
|
|
159
|
+
* the last good settings kept after an invalid edit, or nothing usable (an
|
|
160
|
+
* invalid file that was never valid).
|
|
161
|
+
*/
|
|
162
|
+
export type SttSettingsSource = 'ok' | 'missing' | 'lastGood' | 'invalid';
|
|
163
|
+
export interface ResolvedSttSettings {
|
|
164
|
+
/** The effective settings: the file's, the last good ones after a bad edit, or the empty ones. */
|
|
165
|
+
settings: SttConfigFile;
|
|
166
|
+
source: SttSettingsSource;
|
|
167
|
+
/** Available engines in chain order. */
|
|
168
|
+
engines: ResolvedSttEngine[];
|
|
169
|
+
unavailable: UnavailableSttEngine[];
|
|
170
|
+
/** The file names an enabled local engine that is neither installed nor being installed. */
|
|
171
|
+
needsAutoInstall: boolean;
|
|
172
|
+
errors: string[];
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* @description Turn the loaded settings into the chain a voice note walks:
|
|
176
|
+
* the available engines in order, the skipped ones with their reason, and
|
|
177
|
+
* whether the local engine has to be installed first.
|
|
178
|
+
*/
|
|
179
|
+
export declare function resolveSttSettings(load: SttConfigLoad, facts: SttFacts, options?: SttResolveOptions): ResolvedSttSettings;
|
|
180
|
+
/**
|
|
181
|
+
* @description The i18n key of the notice a voice note gets when NO engine can take it, from the most specific
|
|
182
|
+
* cause down: a broken `stt.json`; the local engine still installing (the voice is not refused for good — send it
|
|
183
|
+
* again); engines that are listed but unusable right now; and none set up (or all switched off by the operator).
|
|
184
|
+
*/
|
|
185
|
+
export declare function getNoEngineNoticeCode(resolved: Pick<ResolvedSttSettings, 'errors' | 'unavailable'>): 'voice.config_invalid' | 'voice.local_installing' | 'voice.engines_unavailable' | 'voice.no_api_key';
|
|
186
|
+
/**
|
|
187
|
+
* @description The `[STT]` log lines for what is wrong with the settings:
|
|
188
|
+
* file errors (with what the bot does instead), skipped engines (a disabled one
|
|
189
|
+
* is the operator's choice, not a problem) and an empty chain (unless the file itself
|
|
190
|
+
* is unusable, which its own error already says). Empty → all well.
|
|
191
|
+
*/
|
|
192
|
+
export declare function getSttReportLines(resolved: ResolvedSttSettings): string[];
|
|
193
|
+
/**
|
|
194
|
+
* @description The request budget for one voice: `baseSeconds` plus
|
|
195
|
+
* `percentOfDuration` % of the voice's length (Telegram's `voice.duration`). A missing length — or a `0`, which
|
|
196
|
+
* Telegram reports for a note whose length it could not read — is "unknown", not a 0-second voice: it is
|
|
197
|
+
* budgeted as {@link unknownVoiceDurationSeconds}, so a long voice without a length is not cut at the bare base.
|
|
198
|
+
* Long voices stay on their engine, they just get more time.
|
|
199
|
+
*/
|
|
200
|
+
export declare function getEngineTimeoutMs(timeout: SttTimeout, durationSeconds: number | undefined): number;
|
|
201
|
+
//# sourceMappingURL=sttSettings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sttSettings.d.ts","sourceRoot":"","sources":["../../src/stt/sttSettings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.resetSttConfigCache = exports.loadSttConfig = exports.gigaamLanguage = exports.defaultGigaamThreads = exports.defaultGigaamWorkers = exports.defaultGigaamIdleMinutes = exports.defaultSttTimeout = exports.sttGigaamWorkerChoices = exports.sttEngineLimit = exports.sttEngineKinds = exports.sttConfigFileName = void 0;
|
|
37
|
+
exports.createEmptySttConfig = createEmptySttConfig;
|
|
38
|
+
exports.clampSttWorkers = clampSttWorkers;
|
|
39
|
+
exports.normaliseSttConfig = normaliseSttConfig;
|
|
40
|
+
exports.validateSttConfig = validateSttConfig;
|
|
41
|
+
exports.getSttConfigPath = getSttConfigPath;
|
|
42
|
+
exports.saveSttConfig = saveSttConfig;
|
|
43
|
+
exports.migrateLegacySttKeys = migrateLegacySttKeys;
|
|
44
|
+
exports.createSttEngineId = createSttEngineId;
|
|
45
|
+
exports.resolveSttSettings = resolveSttSettings;
|
|
46
|
+
exports.getNoEngineNoticeCode = getNoEngineNoticeCode;
|
|
47
|
+
exports.getSttReportLines = getSttReportLines;
|
|
48
|
+
exports.getEngineTimeoutMs = getEngineTimeoutMs;
|
|
49
|
+
const fs = __importStar(require("fs"));
|
|
50
|
+
const os = __importStar(require("os"));
|
|
51
|
+
const zod_1 = require("zod");
|
|
52
|
+
const configDirFile_1 = require("../configDirFile");
|
|
53
|
+
const legacyNames_1 = require("../legacyNames");
|
|
54
|
+
const transcribeAudio_1 = require("../utils/transcribeAudio");
|
|
55
|
+
/**
|
|
56
|
+
* @description The voice-recognition settings: ONE JSON file, `stt.json`, next to
|
|
57
|
+
* the instance's `.env`, holding the engine chain, the language, the local
|
|
58
|
+
* engine's knobs AND the API keys. `/stt` writes it; an operator may hand-edit
|
|
59
|
+
* it, and the next voice note sees the edit (the load is cached by file stamp).
|
|
60
|
+
*
|
|
61
|
+
* Validation is strict and all-or-nothing, like `jira.json`: a typo is an error
|
|
62
|
+
* that NAMES the field and never echoes a value (a key may sit next to it), and
|
|
63
|
+
* an invalid edit keeps the last good settings instead of silently dropping an
|
|
64
|
+
* engine.
|
|
65
|
+
*/
|
|
66
|
+
/** The file in the config dir. */
|
|
67
|
+
exports.sttConfigFileName = 'stt.json';
|
|
68
|
+
exports.sttEngineKinds = ['gigaam', 'groq', 'openai', 'url'];
|
|
69
|
+
/** The most engines one chain holds. */
|
|
70
|
+
exports.sttEngineLimit = 6;
|
|
71
|
+
/** The worker counts `/stt` offers; a hand-edited value is clamped to the nearest one. */
|
|
72
|
+
exports.sttGigaamWorkerChoices = [1, 2, 4, 8];
|
|
73
|
+
exports.defaultSttTimeout = { baseSeconds: 10, percentOfDuration: 25 };
|
|
74
|
+
exports.defaultGigaamIdleMinutes = 15;
|
|
75
|
+
exports.defaultGigaamWorkers = 4;
|
|
76
|
+
/** Intra-op threads per worker; `workers × threads` should not exceed the CPU count. */
|
|
77
|
+
exports.defaultGigaamThreads = 2;
|
|
78
|
+
/** Voice length assumed for the timeout when Telegram did not report one. */
|
|
79
|
+
const unknownVoiceDurationSeconds = 60;
|
|
80
|
+
/** The only language the local engine knows. */
|
|
81
|
+
exports.gigaamLanguage = 'ru';
|
|
82
|
+
const percentDivisor = 100;
|
|
83
|
+
const millisecondsPerSecond = 1000;
|
|
84
|
+
const engineIdRe = /^[a-z0-9]{1,8}$/;
|
|
85
|
+
const languageRe = /^[a-z]{2}$/;
|
|
86
|
+
const maxTimeoutBaseSeconds = 600;
|
|
87
|
+
const maxTimeoutPercent = 400;
|
|
88
|
+
const maxIdleMinutes = 24 * 60; // a day: longer is "never" (0)
|
|
89
|
+
const maxWorkers = 64;
|
|
90
|
+
const maxThreads = 32;
|
|
91
|
+
/** The file holds API keys: owner-only. */
|
|
92
|
+
const configFileMode = 0o600;
|
|
93
|
+
const timeoutSchema = zod_1.z.strictObject({
|
|
94
|
+
baseSeconds: zod_1.z.number().min(1).max(maxTimeoutBaseSeconds),
|
|
95
|
+
percentOfDuration: zod_1.z.number().min(0).max(maxTimeoutPercent),
|
|
96
|
+
});
|
|
97
|
+
const engineSchema = zod_1.z.strictObject({
|
|
98
|
+
id: zod_1.z.string().regex(engineIdRe, 'must be 1-8 lowercase letters or digits'),
|
|
99
|
+
kind: zod_1.z.enum(exports.sttEngineKinds),
|
|
100
|
+
isDisabled: zod_1.z.boolean().optional(),
|
|
101
|
+
timeout: timeoutSchema.optional(),
|
|
102
|
+
url: zod_1.z.string().min(1).optional(),
|
|
103
|
+
model: zod_1.z.string().min(1).optional(),
|
|
104
|
+
apiKey: zod_1.z.string().min(1).optional(),
|
|
105
|
+
});
|
|
106
|
+
const gigaamSchema = zod_1.z.strictObject({
|
|
107
|
+
idleMinutes: zod_1.z.number().int().min(0).max(maxIdleMinutes).optional(),
|
|
108
|
+
workers: zod_1.z.number().int().min(1).max(maxWorkers).optional(),
|
|
109
|
+
threads: zod_1.z.number().int().min(1).max(maxThreads).optional(),
|
|
110
|
+
});
|
|
111
|
+
const rawConfigSchema = zod_1.z.strictObject({
|
|
112
|
+
engines: zod_1.z.array(engineSchema).max(exports.sttEngineLimit).optional(),
|
|
113
|
+
language: zod_1.z.string().regex(languageRe, 'must be a two-letter ISO-639-1 code like ru').nullable().optional(),
|
|
114
|
+
gigaam: gigaamSchema.optional(),
|
|
115
|
+
});
|
|
116
|
+
/** @description The settings of an instance that has no `stt.json`: no engines, auto language. */
|
|
117
|
+
function createEmptySttConfig() {
|
|
118
|
+
return {
|
|
119
|
+
engines: [],
|
|
120
|
+
language: null,
|
|
121
|
+
gigaam: { idleMinutes: exports.defaultGigaamIdleMinutes, workers: exports.defaultGigaamWorkers },
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/** @description The worker count nearest to `workers` among {@link sttGigaamWorkerChoices} (a tie goes to the smaller). */
|
|
125
|
+
function clampSttWorkers(workers) {
|
|
126
|
+
return exports.sttGigaamWorkerChoices.reduce((nearest, choice) => Math.abs(choice - workers) < Math.abs(nearest - workers) ? choice : nearest);
|
|
127
|
+
}
|
|
128
|
+
/** @description `config` with the worker count clamped to a choice `/stt` offers. */
|
|
129
|
+
function normaliseSttConfig(config) {
|
|
130
|
+
return { ...config, gigaam: { ...config.gigaam, workers: clampSttWorkers(config.gigaam.workers) } };
|
|
131
|
+
}
|
|
132
|
+
function getUrlError(url) {
|
|
133
|
+
try {
|
|
134
|
+
const protocol = new URL(url).protocol;
|
|
135
|
+
return protocol === 'http:' || protocol === 'https:' ? null : 'must be an http(s) URL';
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return 'must be an http(s) URL';
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function createConfigFromRaw(raw) {
|
|
142
|
+
const empty = createEmptySttConfig();
|
|
143
|
+
const gigaam = {
|
|
144
|
+
idleMinutes: raw.gigaam?.idleMinutes ?? empty.gigaam.idleMinutes,
|
|
145
|
+
workers: raw.gigaam?.workers ?? empty.gigaam.workers,
|
|
146
|
+
...(raw.gigaam?.threads !== undefined ? { threads: raw.gigaam.threads } : {}),
|
|
147
|
+
};
|
|
148
|
+
return normaliseSttConfig({ engines: raw.engines ?? [], language: raw.language ?? null, gigaam });
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* @description Validate a parsed `stt.json` object. Every error names its field
|
|
152
|
+
* (`stt.json engines.1.timeout.baseSeconds: …`) and never carries a value.
|
|
153
|
+
*/
|
|
154
|
+
function validateSttConfig(parsedJson) {
|
|
155
|
+
const parsed = rawConfigSchema.safeParse(parsedJson);
|
|
156
|
+
if (!parsed.success) {
|
|
157
|
+
return {
|
|
158
|
+
ok: false,
|
|
159
|
+
errors: parsed.error.issues.map((issue) => `stt.json ${issue.path.join('.') || '(root)'}: ${issue.message}`),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
const errors = [];
|
|
163
|
+
const seenIds = new Set();
|
|
164
|
+
let isGigaamSeen = false;
|
|
165
|
+
(parsed.data.engines ?? []).forEach((engine, index) => {
|
|
166
|
+
if (seenIds.has(engine.id))
|
|
167
|
+
errors.push(`stt.json engines.${index}.id: duplicate id`);
|
|
168
|
+
seenIds.add(engine.id);
|
|
169
|
+
if (engine.kind === 'gigaam') {
|
|
170
|
+
if (isGigaamSeen)
|
|
171
|
+
errors.push(`stt.json engines.${index}.kind: the local engine can be listed only once`);
|
|
172
|
+
isGigaamSeen = true;
|
|
173
|
+
}
|
|
174
|
+
const urlError = engine.url === undefined ? null : getUrlError(engine.url);
|
|
175
|
+
if (urlError)
|
|
176
|
+
errors.push(`stt.json engines.${index}.url: ${urlError}`);
|
|
177
|
+
});
|
|
178
|
+
if (errors.length > 0)
|
|
179
|
+
return { ok: false, errors };
|
|
180
|
+
return { ok: true, config: createConfigFromRaw(parsed.data) };
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* @description Where `stt.json` lives: beside the instance's REAL env file (see {@link getConfigDirFilePath} for
|
|
184
|
+
* the rules — a symlinked `.env` is resolved, so the file that holds API keys lands beside the real one).
|
|
185
|
+
*/
|
|
186
|
+
function getSttConfigPath(env = process.env, homeDir = os.homedir()) {
|
|
187
|
+
return (0, configDirFile_1.getConfigDirFilePath)(exports.sttConfigFileName, env, homeDir);
|
|
188
|
+
}
|
|
189
|
+
const sttConfigLoader = (0, configDirFile_1.createConfigFileLoader)({
|
|
190
|
+
fileName: exports.sttConfigFileName,
|
|
191
|
+
createEmpty: createEmptySttConfig,
|
|
192
|
+
validate: validateSttConfig,
|
|
193
|
+
});
|
|
194
|
+
/**
|
|
195
|
+
* @description Read and validate `stt.json`, cached by the file's stamp
|
|
196
|
+
* (mtime, size, inode) so a per-voice call costs one `stat`. A missing file is
|
|
197
|
+
* the empty settings; an unreadable or invalid one keeps the last good settings.
|
|
198
|
+
*/
|
|
199
|
+
exports.loadSttConfig = sttConfigLoader.load;
|
|
200
|
+
/** @description Forget every cached load — for tests, which swap files under one path. */
|
|
201
|
+
exports.resetSttConfigCache = sttConfigLoader.resetCache;
|
|
202
|
+
/**
|
|
203
|
+
* @description Write `config` to `filePath`: validated first (a caller that builds
|
|
204
|
+
* an invalid file has a bug), then written mode 0600 through a temp file and a
|
|
205
|
+
* rename, so a reader never sees half a file.
|
|
206
|
+
*/
|
|
207
|
+
function saveSttConfig(filePath, config) {
|
|
208
|
+
const normalised = normaliseSttConfig(config);
|
|
209
|
+
const validation = validateSttConfig(normalised);
|
|
210
|
+
if (!validation.ok)
|
|
211
|
+
throw new Error(`refusing to write an invalid stt.json: ${validation.errors.join('; ')}`);
|
|
212
|
+
(0, configDirFile_1.writeJsonFileAtomically)(filePath, normalised, configFileMode);
|
|
213
|
+
}
|
|
214
|
+
/** The env variables the one-time migration reads: the only place that does. */
|
|
215
|
+
const legacyGroqKeyName = 'GROQ_API_KEY';
|
|
216
|
+
const legacyOpenAiKeyName = 'OPENAI_API_KEY';
|
|
217
|
+
const legacyKeysDeprecationKey = 'stt-env-keys';
|
|
218
|
+
const legacyKeysDeprecationMessage = 'GROQ_API_KEY/OPENAI_API_KEY in .env is deprecated, voice settings now live in stt.json';
|
|
219
|
+
/**
|
|
220
|
+
* @description The ONE-TIME migration of the pre-`stt.json` setup: with no file
|
|
221
|
+
* yet and `GROQ_API_KEY` / `OPENAI_API_KEY` set, write `stt.json` with those
|
|
222
|
+
* engines (Groq first) and their keys. From then on the env keys are ignored;
|
|
223
|
+
* a process that still sees one says so once. Never overwrites an existing file.
|
|
224
|
+
*/
|
|
225
|
+
function migrateLegacySttKeys(filePath, env = process.env, writeLine) {
|
|
226
|
+
const groqKey = env[legacyGroqKeyName];
|
|
227
|
+
const openAiKey = env[legacyOpenAiKeyName];
|
|
228
|
+
if (!groqKey && !openAiKey)
|
|
229
|
+
return { status: 'noKeys' };
|
|
230
|
+
(0, legacyNames_1.warnLegacyNameOnce)(legacyKeysDeprecationKey, legacyKeysDeprecationMessage, writeLine);
|
|
231
|
+
if (fs.existsSync(filePath))
|
|
232
|
+
return { status: 'fileExists' };
|
|
233
|
+
const config = createEmptySttConfig();
|
|
234
|
+
if (groqKey)
|
|
235
|
+
config.engines.push({ id: createSttEngineId('groq', new Set()), kind: 'groq', apiKey: groqKey });
|
|
236
|
+
if (openAiKey)
|
|
237
|
+
config.engines.push({ id: createSttEngineId('openai', new Set()), kind: 'openai', apiKey: openAiKey });
|
|
238
|
+
try {
|
|
239
|
+
saveSttConfig(filePath, config);
|
|
240
|
+
}
|
|
241
|
+
catch (e) {
|
|
242
|
+
return { status: 'writeFailed', error: (0, configDirFile_1.getCaughtErrnoCode)(e) };
|
|
243
|
+
}
|
|
244
|
+
return { status: 'migrated', engineNames: config.engines.map((engine) => engine.kind) };
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* @description `/stt`'s engine id for a new engine of `kind`: `g` for the local
|
|
248
|
+
* one, else the kind's letter plus the smallest number not taken (`q1`, `o2`, `u1`).
|
|
249
|
+
*/
|
|
250
|
+
function createSttEngineId(kind, takenIds) {
|
|
251
|
+
if (kind === 'gigaam')
|
|
252
|
+
return 'g';
|
|
253
|
+
const letter = kind === 'groq' ? 'q' : kind === 'openai' ? 'o' : 'u';
|
|
254
|
+
let number = 1;
|
|
255
|
+
while (takenIds.has(`${letter}${number}`))
|
|
256
|
+
number++;
|
|
257
|
+
return `${letter}${number}`;
|
|
258
|
+
}
|
|
259
|
+
function getUnavailableReason(engine, config, facts) {
|
|
260
|
+
if (engine.isDisabled)
|
|
261
|
+
return 'disabled';
|
|
262
|
+
switch (engine.kind) {
|
|
263
|
+
case 'gigaam':
|
|
264
|
+
if (!facts.hasOwnerContext)
|
|
265
|
+
return 'noOwnerContext';
|
|
266
|
+
if (config.language !== null && config.language !== exports.gigaamLanguage)
|
|
267
|
+
return 'languageNotSupported';
|
|
268
|
+
if (facts.isGigaamInstalling)
|
|
269
|
+
return 'installing';
|
|
270
|
+
if (!facts.isGigaamInstalled)
|
|
271
|
+
return 'notInstalled';
|
|
272
|
+
return facts.isGigaamUnhealthy ? 'unhealthy' : null;
|
|
273
|
+
case 'groq':
|
|
274
|
+
case 'openai':
|
|
275
|
+
return engine.apiKey ? null : 'missingKey';
|
|
276
|
+
case 'url':
|
|
277
|
+
return engine.url ? null : 'missingUrl';
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
function getEngineName(engine) {
|
|
281
|
+
if (engine.kind !== 'url')
|
|
282
|
+
return engine.kind;
|
|
283
|
+
try {
|
|
284
|
+
return `url:${new URL(engine.url ?? '').host}`;
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
return 'url';
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
/** The endpoint of an engine that needs no process: its key and URL are in the file. */
|
|
291
|
+
function createStaticEndpoint(engine) {
|
|
292
|
+
if (engine.kind === 'groq')
|
|
293
|
+
return (0, transcribeAudio_1.createGroqEndpoint)(engine.apiKey ?? '');
|
|
294
|
+
if (engine.kind === 'openai')
|
|
295
|
+
return (0, transcribeAudio_1.createOpenAiEndpoint)(engine.apiKey ?? '');
|
|
296
|
+
return (0, transcribeAudio_1.createCustomEndpoint)({ url: engine.url ?? '', apiKey: engine.apiKey, model: engine.model });
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* @description Turn the loaded settings into the chain a voice note walks:
|
|
300
|
+
* the available engines in order, the skipped ones with their reason, and
|
|
301
|
+
* whether the local engine has to be installed first.
|
|
302
|
+
*/
|
|
303
|
+
function resolveSttSettings(load, facts, options = {}) {
|
|
304
|
+
const settings = load.config ?? createEmptySttConfig();
|
|
305
|
+
const engines = [];
|
|
306
|
+
const unavailable = [];
|
|
307
|
+
for (const engine of settings.engines) {
|
|
308
|
+
const getEndpoint = engine.kind === 'gigaam' ? options.getGigaamEndpoint : () => Promise.resolve(createStaticEndpoint(engine));
|
|
309
|
+
// No hook to start the process means no owner to start it for.
|
|
310
|
+
const reason = getUnavailableReason(engine, settings, facts) ?? (getEndpoint ? null : 'noOwnerContext');
|
|
311
|
+
if (reason || !getEndpoint) {
|
|
312
|
+
unavailable.push({ id: engine.id, kind: engine.kind, reason: reason ?? 'noOwnerContext' });
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
engines.push({
|
|
316
|
+
id: engine.id,
|
|
317
|
+
kind: engine.kind,
|
|
318
|
+
name: getEngineName(engine),
|
|
319
|
+
timeout: engine.timeout ?? exports.defaultSttTimeout,
|
|
320
|
+
getEndpoint,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
const needsAutoInstall = settings.engines.some((engine) => engine.kind === 'gigaam' && !engine.isDisabled && !facts.isGigaamInstalled && !facts.isGigaamInstalling);
|
|
324
|
+
return {
|
|
325
|
+
settings,
|
|
326
|
+
source: load.status === 'invalid' ? (load.config ? 'lastGood' : 'invalid') : load.status,
|
|
327
|
+
engines,
|
|
328
|
+
unavailable,
|
|
329
|
+
needsAutoInstall,
|
|
330
|
+
errors: load.status === 'invalid' ? load.errors : [],
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
const unavailableReasonTexts = {
|
|
334
|
+
disabled: 'disabled',
|
|
335
|
+
notInstalled: 'not installed',
|
|
336
|
+
installing: 'still installing',
|
|
337
|
+
unhealthy: 'marked unhealthy after repeated start failures',
|
|
338
|
+
languageNotSupported: 'the local engine only knows Russian',
|
|
339
|
+
noOwnerContext: 'it has no owner process to be tied to (a hot supervisor that predates local recognition: restart it)',
|
|
340
|
+
missingKey: 'no API key',
|
|
341
|
+
missingUrl: 'no URL',
|
|
342
|
+
};
|
|
343
|
+
/**
|
|
344
|
+
* @description The i18n key of the notice a voice note gets when NO engine can take it, from the most specific
|
|
345
|
+
* cause down: a broken `stt.json`; the local engine still installing (the voice is not refused for good — send it
|
|
346
|
+
* again); engines that are listed but unusable right now; and none set up (or all switched off by the operator).
|
|
347
|
+
*/
|
|
348
|
+
function getNoEngineNoticeCode(resolved) {
|
|
349
|
+
if (resolved.errors.length > 0)
|
|
350
|
+
return 'voice.config_invalid';
|
|
351
|
+
if (resolved.unavailable.some((engine) => engine.reason === 'installing'))
|
|
352
|
+
return 'voice.local_installing';
|
|
353
|
+
if (resolved.unavailable.some((engine) => engine.reason !== 'disabled'))
|
|
354
|
+
return 'voice.engines_unavailable';
|
|
355
|
+
return 'voice.no_api_key';
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* @description The `[STT]` log lines for what is wrong with the settings:
|
|
359
|
+
* file errors (with what the bot does instead), skipped engines (a disabled one
|
|
360
|
+
* is the operator's choice, not a problem) and an empty chain (unless the file itself
|
|
361
|
+
* is unusable, which its own error already says). Empty → all well.
|
|
362
|
+
*/
|
|
363
|
+
function getSttReportLines(resolved) {
|
|
364
|
+
const errorSuffix = resolved.source === 'lastGood' ? 'keeping the last good settings' : 'no voice settings loaded';
|
|
365
|
+
const lines = resolved.errors.map((error) => `[STT] ${error} (${errorSuffix})`);
|
|
366
|
+
for (const skipped of resolved.unavailable) {
|
|
367
|
+
if (skipped.reason === 'disabled')
|
|
368
|
+
continue;
|
|
369
|
+
lines.push(`[STT] engine ${skipped.id} (${skipped.kind}) is skipped: ${unavailableReasonTexts[skipped.reason]}`);
|
|
370
|
+
}
|
|
371
|
+
if (resolved.engines.length === 0 && resolved.source !== 'invalid') {
|
|
372
|
+
lines.push('[STT] no speech engine is available: voice notes are refused until one is set up');
|
|
373
|
+
}
|
|
374
|
+
return lines;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* @description The request budget for one voice: `baseSeconds` plus
|
|
378
|
+
* `percentOfDuration` % of the voice's length (Telegram's `voice.duration`). A missing length — or a `0`, which
|
|
379
|
+
* Telegram reports for a note whose length it could not read — is "unknown", not a 0-second voice: it is
|
|
380
|
+
* budgeted as {@link unknownVoiceDurationSeconds}, so a long voice without a length is not cut at the bare base.
|
|
381
|
+
* Long voices stay on their engine, they just get more time.
|
|
382
|
+
*/
|
|
383
|
+
function getEngineTimeoutMs(timeout, durationSeconds) {
|
|
384
|
+
const voiceSeconds = durationSeconds !== undefined && durationSeconds > 0 ? durationSeconds : unknownVoiceDurationSeconds;
|
|
385
|
+
return (timeout.baseSeconds + (timeout.percentOfDuration / percentDivisor) * voiceSeconds) * millisecondsPerSecond;
|
|
386
|
+
}
|
|
387
|
+
//# sourceMappingURL=sttSettings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sttSettings.js","sourceRoot":"","sources":["../../src/stt/sttSettings.ts"],"names":[],"mappings":"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"}
|