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
|
@@ -13,19 +13,21 @@ const telegraf_1 = require("telegraf");
|
|
|
13
13
|
const createAdapter_1 = require("../../../adapters/createAdapter");
|
|
14
14
|
const adapterNames_1 = require("../../../adapters/adapterNames");
|
|
15
15
|
const sessionKey_1 = require("../../../sessionKey");
|
|
16
|
-
const sessionKeyCodec_1 = require("../sessionKeyCodec");
|
|
17
16
|
const openCodeAdapter_1 = require("../../../adapters/openCodeAdapter");
|
|
18
|
-
const rateLimiter_1 = require("../../../rateLimiter");
|
|
19
17
|
const i18n_1 = require("../../../i18n");
|
|
20
|
-
const paginateList_1 = require("../../../utils/paginateList");
|
|
21
18
|
const modelPickerPlan_1 = require("../../../utils/modelPickerPlan");
|
|
22
19
|
const modelRecentPlan_1 = require("../../../utils/modelRecentPlan");
|
|
23
20
|
const providerDisconnectPlan_1 = require("../../../utils/providerDisconnectPlan");
|
|
24
21
|
const sendErrorClassifier_1 = require("../../../sendErrorClassifier");
|
|
25
22
|
const modelSetReplyDecision_1 = require("../../../utils/modelSetReplyDecision");
|
|
26
23
|
const effortLevels_1 = require("../../../effortLevels");
|
|
24
|
+
const configDirFile_1 = require("../../../configDirFile");
|
|
25
|
+
const instanceSettings_1 = require("../../../instanceSettings");
|
|
26
|
+
const effortPickerPlan_1 = require("../../../utils/effortPickerPlan");
|
|
27
27
|
const openCodeAuthLogin_1 = require("../../../utils/openCodeAuthLogin");
|
|
28
28
|
const callbackMessage_1 = require("./callbackMessage");
|
|
29
|
+
const modelPage_1 = require("./modelPage");
|
|
30
|
+
const callbackToast_1 = require("./callbackToast");
|
|
29
31
|
const defaultConnectProviderId = 'openai';
|
|
30
32
|
function checkLooksLikeProviderApiKey(value) {
|
|
31
33
|
return value.startsWith('sk-');
|
|
@@ -61,15 +63,6 @@ function getProviderAuthAdapter() {
|
|
|
61
63
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
62
64
|
// /model — two-level provider → models picker
|
|
63
65
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
64
|
-
/**
|
|
65
|
-
* @description Models per page in the `/model` model level. Model names are
|
|
66
|
-
* long, so each gets a full-width row; 10 rows keep the keyboard scroll-free
|
|
67
|
-
* and the numbered text list ~10 short lines — far from Telegram's 4096-char
|
|
68
|
-
* message cap, which the old render-everything list blew past (12 990 chars on
|
|
69
|
-
* a 367-model `openrouter` catalog → every `/model` died with "message is too
|
|
70
|
-
* long" and the topic went silent).
|
|
71
|
-
*/
|
|
72
|
-
const MODEL_PAGE_SIZE = 10;
|
|
73
66
|
/** Model label the thread currently runs, or the localized "default" stand-in. */
|
|
74
67
|
function getCurrentModelLabel(adapter, key) {
|
|
75
68
|
return adapter.getCurrentModel?.(key) || (0, i18n_1.t)('model.current_default');
|
|
@@ -182,29 +175,21 @@ function buildModelPageRender(catalog, providerIndex, page, current, options) {
|
|
|
182
175
|
if (provider === undefined || catalog.hiddenProviders.includes(provider))
|
|
183
176
|
return null;
|
|
184
177
|
const providerModels = catalog.byProvider.get(provider) ?? [];
|
|
185
|
-
const {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
178
|
+
const { rows, pageModels, currentPage, totalPages } = (0, modelPage_1.buildModelPageButtons)({
|
|
179
|
+
provider,
|
|
180
|
+
models: providerModels,
|
|
181
|
+
page,
|
|
182
|
+
current,
|
|
183
|
+
callbacks: {
|
|
184
|
+
buildPage: (targetPage) => (0, modelPickerPlan_1.buildProviderPageCallback)(providerIndex, targetPage),
|
|
185
|
+
buildPick: (modelIndex) => (0, modelPickerPlan_1.buildModelPickCallback)(providerIndex, modelIndex),
|
|
186
|
+
noop: modelPickerPlan_1.modelPickerNoopCallback,
|
|
187
|
+
// No back row when the provider level was skipped — it would lead nowhere.
|
|
188
|
+
back: (0, modelPickerPlan_1.checkHasProviderLevel)(catalog.visibleProviders.length, catalog.hiddenProviders.length)
|
|
189
|
+
? { label: (0, i18n_1.t)('model.back_button'), data: modelPickerPlan_1.modelPickerBackCallback }
|
|
190
|
+
: null,
|
|
191
|
+
},
|
|
192
192
|
});
|
|
193
|
-
if (totalPages > 1) {
|
|
194
|
-
const nav = [];
|
|
195
|
-
if (currentPage > 0) {
|
|
196
|
-
nav.push(telegraf_1.Markup.button.callback((0, i18n_1.t)('model.prev_button'), (0, modelPickerPlan_1.buildProviderPageCallback)(providerIndex, currentPage - 1)));
|
|
197
|
-
}
|
|
198
|
-
nav.push(telegraf_1.Markup.button.callback((0, i18n_1.t)('model.page_button', { page: currentPage + 1, totalPages }), modelPickerPlan_1.modelPickerNoopCallback));
|
|
199
|
-
if (currentPage < totalPages - 1) {
|
|
200
|
-
nav.push(telegraf_1.Markup.button.callback((0, i18n_1.t)('model.next_button'), (0, modelPickerPlan_1.buildProviderPageCallback)(providerIndex, currentPage + 1)));
|
|
201
|
-
}
|
|
202
|
-
rows.push(nav);
|
|
203
|
-
}
|
|
204
|
-
// No back row when the provider level was skipped — it would lead nowhere.
|
|
205
|
-
if ((0, modelPickerPlan_1.checkHasProviderLevel)(catalog.visibleProviders.length, catalog.hiddenProviders.length)) {
|
|
206
|
-
rows.push([telegraf_1.Markup.button.callback((0, i18n_1.t)('model.back_button'), modelPickerPlan_1.modelPickerBackCallback)]);
|
|
207
|
-
}
|
|
208
193
|
const header = (0, i18n_1.t)('model.page_header', {
|
|
209
194
|
provider,
|
|
210
195
|
count: providerModels.length,
|
|
@@ -213,14 +198,14 @@ function buildModelPageRender(catalog, providerIndex, page, current, options) {
|
|
|
213
198
|
current,
|
|
214
199
|
});
|
|
215
200
|
const numberedList = options.isWithNumberedList
|
|
216
|
-
?
|
|
201
|
+
? pageModels.map((modelId, offset) => `${offset + 1}. ${(0, modelPickerPlan_1.getModelShortLabel)(modelId, provider)}`).join('\n')
|
|
217
202
|
: '';
|
|
218
203
|
const hint = options.isWithNumberedList ? (0, i18n_1.t)('model.page_hint') : (0, i18n_1.t)('model.page_hint_buttons_only');
|
|
219
204
|
const text = [header, numberedList, hint].filter((part) => part.length > 0).join('\n\n');
|
|
220
205
|
return {
|
|
221
206
|
text,
|
|
222
207
|
keyboard: telegraf_1.Markup.inlineKeyboard(rows),
|
|
223
|
-
pageModels
|
|
208
|
+
pageModels,
|
|
224
209
|
isNumberedPickArmed: options.isWithNumberedList,
|
|
225
210
|
};
|
|
226
211
|
}
|
|
@@ -240,17 +225,9 @@ async function editModelPickerMessage(ctx, render) {
|
|
|
240
225
|
}
|
|
241
226
|
}
|
|
242
227
|
}
|
|
243
|
-
/**
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
* One callback button per available reasoning-effort level (3 per row);
|
|
247
|
-
* the level matching `current` carries a `✓` marker. Shared by the
|
|
248
|
-
* `/effort` command (initial render) and the `effort_<level>` callback
|
|
249
|
-
* (re-render after a press) so the marker can never drift between the two.
|
|
250
|
-
*/
|
|
251
|
-
function buildEffortKeyboard(levels, current) {
|
|
252
|
-
const buttons = levels.map((l) => telegraf_1.Markup.button.callback(l === current ? `${l} ✓` : l, `effort_${l}`));
|
|
253
|
-
return telegraf_1.Markup.inlineKeyboard(buttons, { columns: 3 });
|
|
228
|
+
/** @description The inline keyboard of an `/effort` picker plan (a thin Markup wrapper over its rows). */
|
|
229
|
+
function buildEffortKeyboard(picker) {
|
|
230
|
+
return telegraf_1.Markup.inlineKeyboard(picker.rows.map((row) => row.map((button) => telegraf_1.Markup.button.callback(button.text, button.data))));
|
|
254
231
|
}
|
|
255
232
|
/**
|
|
256
233
|
* @description Build the model, effort and provider-credential flows over their ports. It returns what the bot's
|
|
@@ -258,7 +235,8 @@ function buildEffortKeyboard(levels, current) {
|
|
|
258
235
|
* bot makes at the positions its neighbouring commands and buttons are registered.
|
|
259
236
|
*/
|
|
260
237
|
function createModelProviders(ports) {
|
|
261
|
-
const { awaitingModelSelection, awaitingSessionSelection, awaitingFolderName, threadModelLists, pendingProviderConnects, connectMethodLists, disconnectProviderLists, startOpenCodeOAuthLogin, bot, command, getState, replyToThread, deleteThreadMessage, authoriseContext, updatePinnedStatus, wakeSleepingSession } = ports;
|
|
238
|
+
const { awaitingModelSelection, awaitingSessionSelection, awaitingFolderName, threadModelLists, pendingProviderConnects, connectMethodLists, disconnectProviderLists, startOpenCodeOAuthLogin, getInstanceSettingsPath, bot, command, getState, replyToThread, editThreadMessage, deleteThreadMessage, authoriseContext, updatePinnedStatus, wakeSleepingSession, checkIsGeneral } = ports;
|
|
239
|
+
const answerWithWholeText = (0, callbackToast_1.createWholeTextAnswerer)(replyToThread);
|
|
262
240
|
/**
|
|
263
241
|
* @description Single choke point for the four `/model`-set paths (the
|
|
264
242
|
* `/model <num>` and `/model <name>` commands, the text-handler numeric pick,
|
|
@@ -280,8 +258,8 @@ function createModelProviders(ports) {
|
|
|
280
258
|
// Read AFTER the switch: a model that does not offer the level in force
|
|
281
259
|
// clears it (`effort.cleared_on_model_switch`), so a pre-switch read would
|
|
282
260
|
// report a level the new model no longer runs. Same resolution rule as
|
|
283
|
-
// `/status` — no `
|
|
284
|
-
const effort =
|
|
261
|
+
// `/status` — no `getEffortState` means the backend has no effort concept at all.
|
|
262
|
+
const effort = (0, effortLevels_1.getThreadEffortView)(adapter, key)?.level ?? null;
|
|
285
263
|
const decision = (0, modelSetReplyDecision_1.getModelSetReplyDecision)({
|
|
286
264
|
hasSetModel: Boolean(adapter.setModel),
|
|
287
265
|
setModelError,
|
|
@@ -607,6 +585,117 @@ function createModelProviders(ports) {
|
|
|
607
585
|
await applyProviderDisconnect(key, providerId);
|
|
608
586
|
});
|
|
609
587
|
}
|
|
588
|
+
/**
|
|
589
|
+
* @description How a regular topic's effort reads against the levels its backend offers: the level its running
|
|
590
|
+
* session uses (else the one its next start will), the next start's level when that differs, and what General's
|
|
591
|
+
* value really is for it. OpenCode offers the model's variants only: a level it lacks runs as the nearest it has,
|
|
592
|
+
* so every level shown is that one.
|
|
593
|
+
*/
|
|
594
|
+
function getTopicEffortAmongLevels(key, adapter, levels) {
|
|
595
|
+
const instanceDefault = (0, effortLevels_1.getEffortAmongLevels)((0, effortLevels_1.getInstanceDefaultEffort)(), levels);
|
|
596
|
+
const view = (0, effortLevels_1.getThreadEffortView)(adapter, key);
|
|
597
|
+
const inForce = view ? (0, effortLevels_1.getEffortAmongLevels)(view.level, levels) : instanceDefault;
|
|
598
|
+
const nextStartLevel = view?.nextStartLevel ? (0, effortLevels_1.getEffortAmongLevels)(view.nextStartLevel, levels) : null;
|
|
599
|
+
return { instanceDefault, inForce, nextStartLevel: nextStartLevel === inForce ? null : nextStartLevel };
|
|
600
|
+
}
|
|
601
|
+
/** @description The levels `adapter` offers the thread; `[]` when it offers none (or cannot say). */
|
|
602
|
+
async function listTopicEffortLevels(key, adapter) {
|
|
603
|
+
try {
|
|
604
|
+
return (await adapter.getAvailableEffortLevels?.(key)) ?? [];
|
|
605
|
+
}
|
|
606
|
+
catch (e) {
|
|
607
|
+
console.error('[Bot] getAvailableEffortLevels:', e);
|
|
608
|
+
return [];
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* @description The `/effort` picker of a regular topic: the level its session uses, where the next start's level
|
|
613
|
+
* comes from (its own pick or General's value), and a button per level the backend offers. `null` when the backend
|
|
614
|
+
* offers none.
|
|
615
|
+
*/
|
|
616
|
+
async function buildTopicEffortPicker(key, adapter) {
|
|
617
|
+
const levels = await listTopicEffortLevels(key, adapter);
|
|
618
|
+
if (levels.length === 0)
|
|
619
|
+
return null;
|
|
620
|
+
return (0, effortPickerPlan_1.buildEffortPicker)({
|
|
621
|
+
isGeneral: false,
|
|
622
|
+
levels,
|
|
623
|
+
...getTopicEffortAmongLevels(key, adapter, levels),
|
|
624
|
+
isOwnPick: (adapter.getOwnEffort?.(key) ?? null) !== null,
|
|
625
|
+
canClear: Boolean(adapter.clearEffort),
|
|
626
|
+
}, i18n_1.t);
|
|
627
|
+
}
|
|
628
|
+
/** @description The `/effort` picker as it stands now, for the screen of `key`; `null` when there is nothing to pick. */
|
|
629
|
+
async function buildEffortPickerFor(key) {
|
|
630
|
+
if (checkIsGeneral(key)) {
|
|
631
|
+
return (0, effortPickerPlan_1.buildEffortPicker)({ isGeneral: true, levels: effortLevels_1.claudeEffortLevels, instanceDefault: (0, effortLevels_1.getInstanceDefaultEffort)() }, i18n_1.t);
|
|
632
|
+
}
|
|
633
|
+
return buildTopicEffortPicker(key, (0, createAdapter_1.getThreadAdapter)(key));
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* @description Re-render the picker a tap came from, text and buttons: the ✓ AND the level named in the text
|
|
637
|
+
* (and its source) follow the new state instead of staying on the previous one. "Message is not modified" (the
|
|
638
|
+
* same tap twice) is swallowed by the shared edit helper.
|
|
639
|
+
*/
|
|
640
|
+
async function rerenderEffortPicker(ctx, key) {
|
|
641
|
+
const messageId = (0, callbackMessage_1.getCallbackMessageId)(ctx);
|
|
642
|
+
if (messageId === null)
|
|
643
|
+
return;
|
|
644
|
+
const picker = await buildEffortPickerFor(key);
|
|
645
|
+
if (!picker)
|
|
646
|
+
return;
|
|
647
|
+
await editThreadMessage(key, messageId, picker.text, buildEffortKeyboard(picker));
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* @description Write the instance default effort (`settings.json`) on top of what the file already holds.
|
|
651
|
+
* Returns `null` on success, else the errno code of the failed write — logged here with the file's path; the
|
|
652
|
+
* caller words it for the user.
|
|
653
|
+
*/
|
|
654
|
+
function saveInstanceDefaultEffort(level) {
|
|
655
|
+
const filePath = getInstanceSettingsPath();
|
|
656
|
+
try {
|
|
657
|
+
(0, instanceSettings_1.saveInstanceSettings)(filePath, { ...(0, instanceSettings_1.loadInstanceSettingsForUpdate)(filePath), defaultEffort: level });
|
|
658
|
+
return null;
|
|
659
|
+
}
|
|
660
|
+
catch (e) {
|
|
661
|
+
const code = (0, configDirFile_1.getCaughtErrnoCode)(e);
|
|
662
|
+
console.warn(`[Settings] could not write ${filePath} (${code})`);
|
|
663
|
+
return code;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
/** @description `/effort` in General: the picker of the instance default, or `/effort <level>` to set it. */
|
|
667
|
+
async function handleGeneralEffortCommand(key, args) {
|
|
668
|
+
if (!args) {
|
|
669
|
+
const picker = await buildEffortPickerFor(key);
|
|
670
|
+
if (picker)
|
|
671
|
+
await replyToThread(key, picker.text, buildEffortKeyboard(picker));
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
674
|
+
if (!(0, effortLevels_1.checkIsClaudeEffortLevel)(args)) {
|
|
675
|
+
await replyToThread(key, (0, i18n_1.t)('effort.invalid_level', { level: args, valid: effortLevels_1.claudeEffortLevels.join(', ') }));
|
|
676
|
+
return;
|
|
677
|
+
}
|
|
678
|
+
const writeCode = saveInstanceDefaultEffort(args);
|
|
679
|
+
await replyToThread(key, writeCode === null
|
|
680
|
+
? (0, i18n_1.t)('effort.general.setConfirmation', { level: args })
|
|
681
|
+
: (0, i18n_1.t)('effort.general.writeFailedNotice', { path: getInstanceSettingsPath(), code: writeCode }));
|
|
682
|
+
}
|
|
683
|
+
/** @description A level button in General: save it as the instance default, confirm, and re-render the picker. */
|
|
684
|
+
async function handleGeneralEffortTap(ctx, key, level) {
|
|
685
|
+
if (!(0, effortLevels_1.checkIsClaudeEffortLevel)(level)) {
|
|
686
|
+
await ctx.answerCbQuery((0, i18n_1.t)('cb.effort_error', { error: level }));
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
const writeCode = saveInstanceDefaultEffort(level);
|
|
690
|
+
if (writeCode !== null) {
|
|
691
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('cb.effort_error', { error: writeCode }));
|
|
692
|
+
await replyToThread(key, (0, i18n_1.t)('effort.general.writeFailedNotice', { path: getInstanceSettingsPath(), code: writeCode }));
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('cb.effort_set', { level }));
|
|
696
|
+
await replyToThread(key, (0, i18n_1.t)('effort.general.setConfirmation', { level }));
|
|
697
|
+
await rerenderEffortPicker(ctx, key);
|
|
698
|
+
}
|
|
610
699
|
function registerModelCommands() {
|
|
611
700
|
command('model', async (_ctx, key, parsed) => {
|
|
612
701
|
const adapter = (0, createAdapter_1.getThreadAdapter)(key);
|
|
@@ -627,8 +716,13 @@ function createModelProviders(ports) {
|
|
|
627
716
|
await showModelPicker(key, adapter);
|
|
628
717
|
});
|
|
629
718
|
command('effort', async (_ctx, key, parsed) => {
|
|
630
|
-
const adapter = (0, createAdapter_1.getThreadAdapter)(key);
|
|
631
719
|
const args = parsed.argsText;
|
|
720
|
+
// General sets the instance default, which needs no backend at all.
|
|
721
|
+
if (checkIsGeneral(key)) {
|
|
722
|
+
await handleGeneralEffortCommand(key, args);
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
const adapter = (0, createAdapter_1.getThreadAdapter)(key);
|
|
632
726
|
// Backend must support the effort contract (both methods are optional).
|
|
633
727
|
if (!adapter.setEffort || !adapter.getAvailableEffortLevels) {
|
|
634
728
|
await replyToThread(key, (0, i18n_1.t)('effort.unsupported_backend', { label: adapter.label }));
|
|
@@ -645,32 +739,23 @@ function createModelProviders(ports) {
|
|
|
645
739
|
const wakeNotice = await wakeSleepingSession(key); // L-D4: apply to the woken session
|
|
646
740
|
if (wakeNotice)
|
|
647
741
|
await replyToThread(key, wakeNotice);
|
|
648
|
-
const
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
await replyToThread(key, (0, i18n_1.t)('effort.set_success', { level: args }));
|
|
742
|
+
const outcome = await adapter.setEffort(key, args);
|
|
743
|
+
await replyToThread(key, outcome.status === 'applied' ? (0, i18n_1.t)('effort.set_success', { level: args }) : outcome.status === 'stored' ? outcome.notice : outcome.reason);
|
|
744
|
+
// A pick the adapter stored but could not apply yet (no agent running) is a pick all the same: the banner
|
|
745
|
+
// follows it. Only a refusal leaves the banner as it was.
|
|
746
|
+
if (outcome.status !== 'refused')
|
|
654
747
|
await updatePinnedStatus(key).catch(() => { });
|
|
655
|
-
}
|
|
656
748
|
return;
|
|
657
749
|
}
|
|
658
|
-
// No arg:
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
levels = await adapter.getAvailableEffortLevels(key);
|
|
662
|
-
}
|
|
663
|
-
catch (e) {
|
|
664
|
-
console.error('[Bot] getAvailableEffortLevels:', e);
|
|
665
|
-
}
|
|
666
|
-
if (levels.length === 0) {
|
|
750
|
+
// No arg: the level in force, where it comes from, and a button per available level.
|
|
751
|
+
const picker = await buildTopicEffortPicker(key, adapter);
|
|
752
|
+
if (!picker) {
|
|
667
753
|
// Empty means the current model declares no variants (OpenCode) or the
|
|
668
754
|
// backend reports no levels — not an error, just nothing to pick.
|
|
669
755
|
await replyToThread(key, (0, i18n_1.t)('effort.not_available'));
|
|
670
756
|
return;
|
|
671
757
|
}
|
|
672
|
-
|
|
673
|
-
await replyToThread(key, (0, i18n_1.t)('effort.choose', { current: cur ?? (0, i18n_1.t)('effort.current_none') }), buildEffortKeyboard(levels, cur));
|
|
758
|
+
await replyToThread(key, picker.text, buildEffortKeyboard(picker));
|
|
674
759
|
});
|
|
675
760
|
}
|
|
676
761
|
function registerModelCallbacks() {
|
|
@@ -724,14 +809,14 @@ function createModelProviders(ports) {
|
|
|
724
809
|
}
|
|
725
810
|
const { isOk, message, setModelError, displayLabel } = await applyModelSelection(adapter, key, modelId);
|
|
726
811
|
if (!isOk) {
|
|
727
|
-
await ctx
|
|
812
|
+
await answerWithWholeText(ctx, key, (0, i18n_1.t)('cb.model_error', { error: setModelError ?? message }));
|
|
728
813
|
return;
|
|
729
814
|
}
|
|
730
|
-
await
|
|
815
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('cb.model_set', { model: displayLabel.split('/').pop() || displayLabel }));
|
|
731
816
|
// The pick is made, so the page's bare-digit affordance must go (an armed
|
|
732
817
|
// thread swallows a later ordinary "3" prompt) — and with it the numbers in
|
|
733
818
|
// the text. Re-render the SAME page so the ✓ moves to the model just picked.
|
|
734
|
-
const refreshed = buildModelPageRender(catalog, providerIndex, Math.floor(modelIndex /
|
|
819
|
+
const refreshed = buildModelPageRender(catalog, providerIndex, Math.floor(modelIndex / modelPage_1.modelPageSize), getCurrentModelLabel(adapter, key), { isWithNumberedList: false });
|
|
735
820
|
if (refreshed) {
|
|
736
821
|
applyModelPagePickArming(key, refreshed);
|
|
737
822
|
await editModelPickerMessage(ctx, refreshed);
|
|
@@ -775,10 +860,10 @@ function createModelProviders(ports) {
|
|
|
775
860
|
}
|
|
776
861
|
const { isOk, message, setModelError, displayLabel } = await applyModelSelection(adapter, key, modelId);
|
|
777
862
|
if (!isOk) {
|
|
778
|
-
await ctx
|
|
863
|
+
await answerWithWholeText(ctx, key, (0, i18n_1.t)('cb.model_error', { error: setModelError ?? message }));
|
|
779
864
|
return;
|
|
780
865
|
}
|
|
781
|
-
await
|
|
866
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('cb.model_set', { model: displayLabel.split('/').pop() || displayLabel }));
|
|
782
867
|
// Re-render the SAME level: the pick just moved to the head and takes the ✓.
|
|
783
868
|
await refreshRecentModelsLevel(ctx, key);
|
|
784
869
|
await replyToThread(key, message);
|
|
@@ -799,7 +884,7 @@ function createModelProviders(ports) {
|
|
|
799
884
|
return;
|
|
800
885
|
}
|
|
801
886
|
await getState().setModelProviderHidden(provider, true);
|
|
802
|
-
await
|
|
887
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('cb.model_hidden', { provider }));
|
|
803
888
|
await refreshModelProviderLevel(ctx, key);
|
|
804
889
|
});
|
|
805
890
|
bot.action(modelPickerPlan_1.providerShowCallbackRe, async (ctx) => {
|
|
@@ -815,7 +900,7 @@ function createModelProviders(ports) {
|
|
|
815
900
|
return;
|
|
816
901
|
}
|
|
817
902
|
await getState().setModelProviderHidden(provider, false);
|
|
818
|
-
await
|
|
903
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('cb.model_shown', { provider }));
|
|
819
904
|
await refreshModelProviderLevel(ctx, key);
|
|
820
905
|
});
|
|
821
906
|
// «⬅️ providers» — back to the provider level.
|
|
@@ -867,10 +952,10 @@ function createModelProviders(ports) {
|
|
|
867
952
|
}
|
|
868
953
|
const { isOk, message, setModelError, displayLabel } = await applyModelSelection(adapter, key, modelId);
|
|
869
954
|
if (!isOk) {
|
|
870
|
-
await ctx
|
|
955
|
+
await answerWithWholeText(ctx, key, (0, i18n_1.t)('cb.model_error', { error: setModelError ?? message }));
|
|
871
956
|
return;
|
|
872
957
|
}
|
|
873
|
-
await
|
|
958
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('cb.model_set', { model: displayLabel.split('/').pop() || displayLabel }));
|
|
874
959
|
await replyToThread(key, message);
|
|
875
960
|
});
|
|
876
961
|
bot.action(/^connm_(\d+)$/, async (ctx) => {
|
|
@@ -896,17 +981,21 @@ function createModelProviders(ports) {
|
|
|
896
981
|
armProviderConnect(key, entry.providerId);
|
|
897
982
|
await replyToThread(key, (0, i18n_1.t)('connect.prompt_key', { provider: entry.providerId }));
|
|
898
983
|
});
|
|
899
|
-
bot.action(
|
|
984
|
+
bot.action(effortPickerPlan_1.effortLevelCallbackRe, async (ctx) => {
|
|
900
985
|
const key = await authoriseContext(ctx);
|
|
901
986
|
if (!key) {
|
|
902
987
|
await ctx.answerCbQuery((0, i18n_1.t)('cb.access_denied'));
|
|
903
988
|
return;
|
|
904
989
|
}
|
|
905
990
|
const level = ctx.match[1];
|
|
991
|
+
if (checkIsGeneral(key)) {
|
|
992
|
+
await handleGeneralEffortTap(ctx, key, level);
|
|
993
|
+
return;
|
|
994
|
+
}
|
|
906
995
|
const adapter = (0, createAdapter_1.getThreadAdapter)(key);
|
|
907
996
|
// No `checkIsActive` gate — effort is persisted pre-session (mirrors the
|
|
908
|
-
// `/effort` command and `/model`). The adapter returns its own notice
|
|
909
|
-
// pick can't apply live;
|
|
997
|
+
// `/effort` command and `/model`). The adapter returns its own notice when the
|
|
998
|
+
// pick can't apply live; it is shown whole (see below).
|
|
910
999
|
if (!adapter.setEffort) {
|
|
911
1000
|
await ctx.answerCbQuery((0, i18n_1.t)('cb.not_supported', { label: adapter.label }));
|
|
912
1001
|
return;
|
|
@@ -914,40 +1003,42 @@ function createModelProviders(ports) {
|
|
|
914
1003
|
const wakeNotice = await wakeSleepingSession(key); // L-D4: apply to the woken session
|
|
915
1004
|
if (wakeNotice)
|
|
916
1005
|
await replyToThread(key, wakeNotice);
|
|
917
|
-
const
|
|
918
|
-
if (
|
|
919
|
-
await ctx
|
|
1006
|
+
const outcome = await adapter.setEffort(key, level);
|
|
1007
|
+
if (outcome.status === 'refused') {
|
|
1008
|
+
await answerWithWholeText(ctx, key, (0, i18n_1.t)('cb.effort_error', { error: outcome.reason }));
|
|
920
1009
|
return;
|
|
921
1010
|
}
|
|
922
|
-
|
|
923
|
-
|
|
1011
|
+
if (outcome.status === 'stored') {
|
|
1012
|
+
// Made, but no agent is running to apply it: what follows a pick follows this one too — only the toast carries
|
|
1013
|
+
// the notice (whole) instead of "set".
|
|
1014
|
+
await answerWithWholeText(ctx, key, outcome.notice);
|
|
1015
|
+
}
|
|
1016
|
+
else {
|
|
1017
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('cb.effort_set', { level }));
|
|
1018
|
+
await replyToThread(key, (0, i18n_1.t)('effort.set_success', { level }));
|
|
1019
|
+
}
|
|
924
1020
|
await updatePinnedStatus(key).catch(() => { });
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
catch (e) {
|
|
935
|
-
console.error('[effort_cb] getAvailableEffortLevels:', e);
|
|
936
|
-
}
|
|
937
|
-
if (levels.length > 0) {
|
|
938
|
-
const cur = adapter.getEffort?.(key) ?? level;
|
|
939
|
-
const keyboard = buildEffortKeyboard(levels, cur);
|
|
940
|
-
try {
|
|
941
|
-
await (0, rateLimiter_1.enqueueSend)(key, () => bot.telegram.editMessageReplyMarkup((0, sessionKeyCodec_1.getTelegramChatId)(key), cbMsg.message_id, undefined, keyboard.reply_markup));
|
|
942
|
-
}
|
|
943
|
-
catch (e) {
|
|
944
|
-
const desc = (0, sendErrorClassifier_1.checkIsApiError)(e) ? (0, sendErrorClassifier_1.getErrorDescription)(e) : '';
|
|
945
|
-
if (!/message is not modified/i.test(desc)) {
|
|
946
|
-
console.warn('[effort_cb] keyboard re-render failed:', desc || e);
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
}
|
|
1021
|
+
await rerenderEffortPicker(ctx, key);
|
|
1022
|
+
});
|
|
1023
|
+
// «As in General»: drop the topic's own pick. Registered with the level buttons: `effortsame` has no
|
|
1024
|
+
// underscore, so `effortLevelCallbackRe` never takes it.
|
|
1025
|
+
bot.action(effortPickerPlan_1.effortSameCallback, async (ctx) => {
|
|
1026
|
+
const key = await authoriseContext(ctx);
|
|
1027
|
+
if (!key) {
|
|
1028
|
+
await ctx.answerCbQuery((0, i18n_1.t)('cb.access_denied'));
|
|
1029
|
+
return;
|
|
950
1030
|
}
|
|
1031
|
+
const adapter = (0, createAdapter_1.getThreadAdapter)(key);
|
|
1032
|
+
if (!adapter.clearEffort) {
|
|
1033
|
+
await ctx.answerCbQuery((0, i18n_1.t)('cb.not_supported', { label: adapter.label }));
|
|
1034
|
+
return;
|
|
1035
|
+
}
|
|
1036
|
+
await adapter.clearEffort(key);
|
|
1037
|
+
const { inForce: level } = getTopicEffortAmongLevels(key, adapter, await listTopicEffortLevels(key, adapter));
|
|
1038
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('cb.effort_same', { level }));
|
|
1039
|
+
await replyToThread(key, (0, i18n_1.t)('effort.sameAsGeneralConfirmation', { level }));
|
|
1040
|
+
await updatePinnedStatus(key).catch(() => { });
|
|
1041
|
+
await rerenderEffortPicker(ctx, key);
|
|
951
1042
|
});
|
|
952
1043
|
}
|
|
953
1044
|
return {
|
|
@@ -955,6 +1046,7 @@ function createModelProviders(ports) {
|
|
|
955
1046
|
applyProviderDisconnect,
|
|
956
1047
|
handleProviderConnectKey,
|
|
957
1048
|
applyNumberedModelPick,
|
|
1049
|
+
applyModelSelection,
|
|
958
1050
|
applyModelPagePickArming,
|
|
959
1051
|
checkIsNumberedModelPickArmed,
|
|
960
1052
|
getNumberedModelPick,
|