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
|
@@ -4,19 +4,26 @@ exports.createClaudeAccounts = createClaudeAccounts;
|
|
|
4
4
|
/**
|
|
5
5
|
* `/accounts` โ every account the bot works with, on one screen: the Claude accounts (profiles) with their usage
|
|
6
6
|
* (which one a topic's Claude sessions run on, add / re-login / remove) and the OpenCode providers the server is
|
|
7
|
-
* authenticated for (
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* authenticated for (switch the topic to one through the shared model page / connect / disconnect; a ChatGPT
|
|
8
|
+
* subscription shows its usage like a Claude account). The title and the โ say where the topic REALLY runs, OpenCode
|
|
9
|
+
* included. `/account`, `/connect` and `/disconnect` stay as hidden aliases; the OpenCode flows themselves live in
|
|
10
|
+
* `modelProviders.ts` and are only entered from here through ports. See README.md in this folder and
|
|
11
|
+
* `utils/claudeProfiles.ts`.
|
|
10
12
|
*/
|
|
11
13
|
const telegraf_1 = require("telegraf");
|
|
12
14
|
const sessionKey_1 = require("../../../sessionKey");
|
|
13
15
|
const i18n_1 = require("../../../i18n");
|
|
16
|
+
const fallbackChain_1 = require("../../../utils/fallbackChain");
|
|
17
|
+
const openCodeUsage_1 = require("../../../utils/openCodeUsage");
|
|
18
|
+
const modelPickerPlan_1 = require("../../../utils/modelPickerPlan");
|
|
14
19
|
const claudeProfiles_1 = require("../../../utils/claudeProfiles");
|
|
15
20
|
const claudeProfileUsageLines_1 = require("../../../utils/claudeProfileUsageLines");
|
|
16
21
|
const claudeUsageRefresher_1 = require("../../../utils/claudeUsageRefresher");
|
|
17
22
|
const claudeAccountPickerPlan_1 = require("../../../utils/claudeAccountPickerPlan");
|
|
18
23
|
const openCodeAdapter_1 = require("../../../adapters/openCodeAdapter");
|
|
19
24
|
const callbackMessage_1 = require("./callbackMessage");
|
|
25
|
+
const callbackToast_1 = require("./callbackToast");
|
|
26
|
+
const modelPage_1 = require("./modelPage");
|
|
20
27
|
/** Screens whose provider snapshot is kept (the newest); an older keyboard is refused as expired. */
|
|
21
28
|
const providerSnapshotLimit = 50;
|
|
22
29
|
/**
|
|
@@ -25,7 +32,8 @@ const providerSnapshotLimit = 50;
|
|
|
25
32
|
* auth-status sink the sign-in driver reports to.
|
|
26
33
|
*/
|
|
27
34
|
function createClaudeAccounts(ports) {
|
|
28
|
-
const { bot, command, getState, replyToThread, editThreadMessage, authoriseContext, withThreadLocale, checkIsGeneral, getDataDir, getInstanceTimezone, refreshClaudeUsage, readClaudeAuthStatus, startClaudeProfileLogin, applyClaudeProfile, applyClaudeProfileEverywhere, detectOpenCodeProviders, disconnectOpenCodeProvider, startOpenCodeConnect, applyAutoSwitch, getHomeClaudeDir, } = ports;
|
|
35
|
+
const { bot, command, getState, replyToThread, editThreadMessage, authoriseContext, withThreadLocale, checkIsGeneral, getDataDir, getInstanceTimezone, refreshClaudeUsage, readClaudeAuthStatus, startClaudeProfileLogin, applyClaudeProfile, applyClaudeProfileEverywhere, switchTopicByOperator, detectOpenCodeProviders, listOpenCodeModels, getTopicRun, disconnectOpenCodeProvider, startOpenCodeConnect, applyAutoSwitch, getHomeClaudeDir, } = ports;
|
|
36
|
+
const answerWithWholeText = (0, callbackToast_1.createWholeTextAnswerer)(replyToThread);
|
|
29
37
|
/**
|
|
30
38
|
* Topics whose next plain message is an answer to ยซโยป: the name of a new Claude profile, or the id of the
|
|
31
39
|
* OpenCode provider to connect. One capture per topic; armed by the buttons / `add`, disarmed by a slash
|
|
@@ -33,16 +41,14 @@ function createClaudeAccounts(ports) {
|
|
|
33
41
|
*/
|
|
34
42
|
const awaitingProfileName = new Map();
|
|
35
43
|
/** The OpenCode providers each screen MESSAGE listed โ its disconnect buttons carry an index into this. */
|
|
44
|
+
/** Per MESSAGE, keyed by chat + message id (`buildMessageSnapshotKey`): a message id is unique only within one chat. */
|
|
36
45
|
const providerSnapshots = new Map();
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
break;
|
|
44
|
-
providerSnapshots.delete(oldest);
|
|
45
|
-
}
|
|
46
|
+
/** The provider whose model page a screen MESSAGE shows, with the models its buttons index (dropped when the screen is re-rendered). */
|
|
47
|
+
const pageSnapshots = new Map();
|
|
48
|
+
function rememberProviders(key, messageId, providers) {
|
|
49
|
+
const snapshotKey = (0, callbackMessage_1.buildMessageSnapshotKey)(key, messageId);
|
|
50
|
+
pageSnapshots.delete(snapshotKey);
|
|
51
|
+
(0, callbackMessage_1.rememberBoundedSnapshot)(providerSnapshots, snapshotKey, providers, providerSnapshotLimit);
|
|
46
52
|
}
|
|
47
53
|
async function readOpenCodeProviders() {
|
|
48
54
|
try {
|
|
@@ -53,9 +59,31 @@ function createClaudeAccounts(ports) {
|
|
|
53
59
|
return [];
|
|
54
60
|
}
|
|
55
61
|
}
|
|
56
|
-
|
|
62
|
+
/** The Claude account a topic's next Claude session takes: its own pick, else the instance default. */
|
|
63
|
+
function resolveClaudeAccountName(key, isGeneral) {
|
|
57
64
|
return isGeneral ? getState().getClaudeProfileGlobalDefault() : getState().resolveClaudeProfileName(key);
|
|
58
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* The account the โ sits on. General: the instance default. A topic: the account its Claude session RUNS on (which is
|
|
68
|
+
* not the pick while a switch is deferred), no account while it runs OpenCode, and โ with no agent โ the pick the next
|
|
69
|
+
* start takes.
|
|
70
|
+
*/
|
|
71
|
+
function resolveActiveName(key, isGeneral) {
|
|
72
|
+
if (isGeneral)
|
|
73
|
+
return getState().getClaudeProfileGlobalDefault();
|
|
74
|
+
const run = getTopicRun(key);
|
|
75
|
+
if (run.family === 'opencode')
|
|
76
|
+
return null;
|
|
77
|
+
return run.rung?.backend === 'claude' ? run.rung.profile : resolveClaudeAccountName(key, false);
|
|
78
|
+
}
|
|
79
|
+
/** Where the topic runs, for the title: `Claude ยซperfยป`, `OpenCode openai/gpt-5`, or `OpenCode` while its model is unknown. */
|
|
80
|
+
function formatRunLabel(key) {
|
|
81
|
+
const run = getTopicRun(key);
|
|
82
|
+
if (run.family === 'opencode') {
|
|
83
|
+
return run.rung?.backend === 'opencode' ? `${(0, i18n_1.t)('fallback.backendOpenCode')} ${run.rung.providerId}/${run.rung.modelId}` : (0, i18n_1.t)('fallback.backendOpenCode');
|
|
84
|
+
}
|
|
85
|
+
return `${(0, i18n_1.t)('fallback.backendClaude')} ยซ${resolveActiveName(key, false) ?? resolveClaudeAccountName(key, false)}ยป`;
|
|
86
|
+
}
|
|
59
87
|
/** The config directory of a profile; `null` for `default`. */
|
|
60
88
|
function resolveDir(name) {
|
|
61
89
|
return (0, claudeProfiles_1.resolveClaudeProfileDir)(getDataDir(), name);
|
|
@@ -147,33 +175,62 @@ function createClaudeAccounts(ports) {
|
|
|
147
175
|
topicCounts,
|
|
148
176
|
});
|
|
149
177
|
}
|
|
178
|
+
/** How a provider is signed in, for its row: ยซChatGPT subscriptionยป / ยซAPI keyยป; nothing for a kind we have no word for. */
|
|
179
|
+
function formatProviderAuthKind(providerId) {
|
|
180
|
+
const kind = getState().getOpenCodeProviderUsage(providerId)?.authKind;
|
|
181
|
+
if (kind === 'apiKey')
|
|
182
|
+
return (0, i18n_1.t)('accounts.providerApiKey');
|
|
183
|
+
return kind === 'subscription' && providerId === openCodeUsage_1.chatGptProviderId ? (0, i18n_1.t)('accounts.providerSubscription') : '';
|
|
184
|
+
}
|
|
185
|
+
/** The connected providers as text: `โ openai โ ChatGPT subscription`, its usage windows hanging under it like an account's. */
|
|
186
|
+
function formatProviderList(providers, rung) {
|
|
187
|
+
const nowMs = Date.now();
|
|
188
|
+
return providers.map((provider) => {
|
|
189
|
+
const kind = formatProviderAuthKind(provider);
|
|
190
|
+
const usageLines = (0, claudeProfileUsageLines_1.formatClaudeProfileUsageLines)(getState().getOpenCodeProviderUsage(provider), getInstanceTimezone(), nowMs);
|
|
191
|
+
return `${(0, fallbackChain_1.getRunningModelOfProvider)(rung, provider) === null ? 'โข' : 'โ'} ${provider}${kind === '' ? '' : ` โ ${kind}`}${usageLines.map((line) => `\n${line}`).join('')}`;
|
|
192
|
+
}).join('\n');
|
|
193
|
+
}
|
|
194
|
+
/** A provider's pick button in a topic: `โ openai ยท gpt-5` where the topic runs, the bare provider elsewhere. */
|
|
195
|
+
function formatProviderRowButton(provider, rung) {
|
|
196
|
+
const runningModel = (0, fallbackChain_1.getRunningModelOfProvider)(rung, provider);
|
|
197
|
+
return runningModel === null ? provider : `โ ${provider} ยท ${runningModel}`;
|
|
198
|
+
}
|
|
150
199
|
/** The main screen: text + keyboard, for the topic (or General), and the provider list the keyboard indexes. */
|
|
151
200
|
async function buildPicker(key, isGeneral) {
|
|
152
201
|
const [rows, providers] = await Promise.all([buildPickerRows(key, isGeneral), readOpenCodeProviders()]);
|
|
153
202
|
const list = rows.map(formatRow).join('\n');
|
|
154
|
-
const
|
|
203
|
+
const run = getTopicRun(key);
|
|
155
204
|
const title = isGeneral
|
|
156
|
-
? (0, i18n_1.t)('account.titleGeneral', { name:
|
|
157
|
-
: (0, i18n_1.t)('account.title', {
|
|
205
|
+
? (0, i18n_1.t)('account.titleGeneral', { name: resolveClaudeAccountName(key, true), list })
|
|
206
|
+
: (0, i18n_1.t)('account.title', { current: formatRunLabel(key), list });
|
|
158
207
|
const openCodeSection = providers.length === 0
|
|
159
208
|
? (0, i18n_1.t)('accounts.openCodeNone')
|
|
160
|
-
: (0, i18n_1.t)('accounts.openCodeSection', { list: providers
|
|
209
|
+
: (0, i18n_1.t)('accounts.openCodeSection', { list: formatProviderList(providers, isGeneral ? null : run.rung) });
|
|
161
210
|
const isDefaultRemoved = getState().getClaudeProfileInfo(claudeProfiles_1.defaultClaudeProfileName)?.isRemoved === true;
|
|
162
211
|
const removedNote = isDefaultRemoved ? `\n\n${(0, i18n_1.t)('accounts.defaultRemovedNote')}` : '';
|
|
163
212
|
// The usage hint (which says the percentages are USED) follows the account list it explains.
|
|
164
|
-
const
|
|
165
|
-
|
|
213
|
+
const buttonsHint = (0, i18n_1.t)(isGeneral ? 'accounts.buttonsHintGeneral' : 'accounts.buttonsHint');
|
|
214
|
+
const text = `${title}${removedNote}\n\n${(0, i18n_1.t)('account.usageHint')}\n\n${openCodeSection}\n\n${buttonsHint}\n\n${(0, i18n_1.t)('account.autoSwitchHint')}`;
|
|
215
|
+
// One row per Claude account: pick it (โ = where the topic runs), sign it in again, remove it (`default` too: signs it out).
|
|
166
216
|
const keyboardRows = rows.map((row) => [
|
|
167
217
|
telegraf_1.Markup.button.callback(formatRowButton(row), (0, claudeAccountPickerPlan_1.buildAccountUseCallback)(row.name)),
|
|
168
218
|
telegraf_1.Markup.button.callback('๐', (0, claudeAccountPickerPlan_1.buildAccountLoginCallback)(row.name)),
|
|
169
219
|
telegraf_1.Markup.button.callback('๐', (0, claudeAccountPickerPlan_1.buildAccountRemoveCallback)(row.name)),
|
|
170
220
|
]);
|
|
171
|
-
// A provider row mirrors it
|
|
221
|
+
// A provider row mirrors it. In a topic its caption is the pick (the model page follows), ๐ connects it again and
|
|
222
|
+
// ๐ disconnects it; in General a provider can only be connected or disconnected: ยซ๐ Disconnect Xยป and ๐.
|
|
172
223
|
providers.forEach((provider, index) => {
|
|
173
|
-
keyboardRows.push(
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
224
|
+
keyboardRows.push(isGeneral
|
|
225
|
+
? [
|
|
226
|
+
telegraf_1.Markup.button.callback((0, i18n_1.t)('accounts.disconnectButton', { provider }), (0, claudeAccountPickerPlan_1.buildAccountDisconnectCallback)(index)),
|
|
227
|
+
telegraf_1.Markup.button.callback('๐', (0, claudeAccountPickerPlan_1.buildAccountReconnectCallback)(index)),
|
|
228
|
+
]
|
|
229
|
+
: [
|
|
230
|
+
telegraf_1.Markup.button.callback(formatProviderRowButton(provider, run.rung), (0, claudeAccountPickerPlan_1.buildAccountOpenCodeUseCallback)(index)),
|
|
231
|
+
telegraf_1.Markup.button.callback('๐', (0, claudeAccountPickerPlan_1.buildAccountReconnectCallback)(index)),
|
|
232
|
+
telegraf_1.Markup.button.callback('๐', (0, claudeAccountPickerPlan_1.buildAccountDisconnectCallback)(index)),
|
|
233
|
+
]);
|
|
177
234
|
});
|
|
178
235
|
keyboardRows.push([
|
|
179
236
|
telegraf_1.Markup.button.callback((0, i18n_1.t)('accounts.addClaudeButton'), claudeAccountPickerPlan_1.accountAddCallback),
|
|
@@ -191,7 +248,7 @@ function createClaudeAccounts(ports) {
|
|
|
191
248
|
const picker = await buildPicker(key, isGeneral);
|
|
192
249
|
const messageId = await replyToThread(key, picker.text, picker.keyboard);
|
|
193
250
|
if (messageId !== null)
|
|
194
|
-
rememberProviders(messageId, picker.providers);
|
|
251
|
+
rememberProviders(key, messageId, picker.providers);
|
|
195
252
|
}
|
|
196
253
|
/** A sub-picker: one button per profile (`default` included only when `includeDefault`), plus ยซBackยป. */
|
|
197
254
|
function buildProfileChoiceKeyboard(buildCallback, includeDefault) {
|
|
@@ -205,7 +262,7 @@ function createClaudeAccounts(ports) {
|
|
|
205
262
|
if (messageId === null)
|
|
206
263
|
return;
|
|
207
264
|
const picker = await buildPicker(key, isGeneral);
|
|
208
|
-
rememberProviders(messageId, picker.providers);
|
|
265
|
+
rememberProviders(key, messageId, picker.providers);
|
|
209
266
|
await editThreadMessage(key, messageId, picker.text, picker.keyboard);
|
|
210
267
|
}
|
|
211
268
|
function describeApplyOutcome(outcome) {
|
|
@@ -216,7 +273,9 @@ function createClaudeAccounts(ports) {
|
|
|
216
273
|
* button. A regular topic sets its own pick and its live session follows at once (idle: re-spawned, same
|
|
217
274
|
* conversation; working: at turn end; sleeping: at the next resume). General sets the instance default and
|
|
218
275
|
* every topic that follows the default is moved the same way. A profile that is not signed in is refused:
|
|
219
|
-
* a session started under it would only fail with a logged-out error.
|
|
276
|
+
* a session started under it would only fail with a logged-out error. On a topic that runs OpenCode the pick is
|
|
277
|
+
* a switch to Claude (`switchTopicByOperator`, which also makes the limit move while a usage-limit wait is armed): the answer
|
|
278
|
+
* is then the question already posted (`null`: nothing to say) or the line that the topic switched.
|
|
220
279
|
*/
|
|
221
280
|
async function applyPick(key, isGeneral, name) {
|
|
222
281
|
if (!checkIsKnownProfile(name))
|
|
@@ -232,9 +291,8 @@ function createClaudeAccounts(ports) {
|
|
|
232
291
|
await applyClaudeProfileEverywhere();
|
|
233
292
|
return (0, i18n_1.t)('account.setGlobal', { name });
|
|
234
293
|
}
|
|
235
|
-
await
|
|
236
|
-
|
|
237
|
-
return (0, i18n_1.t)('account.setThisTopic', { name, apply: describeApplyOutcome(outcome) });
|
|
294
|
+
const outcome = await switchTopicByOperator(key, { backend: 'claude', profile: name, model: null });
|
|
295
|
+
return outcome.kind === 'asked' ? null : outcome.text;
|
|
238
296
|
}
|
|
239
297
|
/** A topic drops its own pick; its session follows the instance default from now on. */
|
|
240
298
|
async function applyFollowDefault(key) {
|
|
@@ -376,6 +434,50 @@ function createClaudeAccounts(ports) {
|
|
|
376
434
|
if (message)
|
|
377
435
|
await replyToThread(key, message);
|
|
378
436
|
}
|
|
437
|
+
// โโ a provider as a pick: its model page โโ
|
|
438
|
+
/** The provider's model page in the screen's message (the shared page builder), and the snapshot its buttons index. */
|
|
439
|
+
async function showProviderModelPage(key, messageId, providerId, models, page) {
|
|
440
|
+
const shown = (0, modelPage_1.buildOpenCodeProviderPage)({
|
|
441
|
+
providerId,
|
|
442
|
+
models,
|
|
443
|
+
page,
|
|
444
|
+
rung: getTopicRun(key).rung,
|
|
445
|
+
limits: getState().getOpenCodeModelLimits(),
|
|
446
|
+
timezone: getInstanceTimezone(),
|
|
447
|
+
nowMs: Date.now(),
|
|
448
|
+
callbacks: {
|
|
449
|
+
buildPage: claudeAccountPickerPlan_1.buildAccountOpenCodePageCallback,
|
|
450
|
+
buildPick: claudeAccountPickerPlan_1.buildAccountOpenCodeModelCallback,
|
|
451
|
+
noop: modelPickerPlan_1.modelPickerNoopCallback,
|
|
452
|
+
back: { label: (0, i18n_1.t)('fallback.backButton'), data: claudeAccountPickerPlan_1.accountBackCallback },
|
|
453
|
+
},
|
|
454
|
+
});
|
|
455
|
+
(0, callbackMessage_1.rememberBoundedSnapshot)(pageSnapshots, (0, callbackMessage_1.buildMessageSnapshotKey)(key, messageId), { providerId, models }, providerSnapshotLimit);
|
|
456
|
+
await editThreadMessage(key, messageId, shown.text, shown.keyboard);
|
|
457
|
+
}
|
|
458
|
+
/** What the shared provider-pick handlers need from this screen: the switch path, the toast and the way back to the screen. */
|
|
459
|
+
function buildPickDeps(ctx, key, messageId, isGeneral) {
|
|
460
|
+
return { ctx, key, switchTopicByOperator, answerWholeText: answerWithWholeText, rerender: () => rerenderPicker(key, messageId, isGeneral) };
|
|
461
|
+
}
|
|
462
|
+
/** `/accounts use <provider>/<model>`: the model a topic runs, through the same path as a tap; never in General. */
|
|
463
|
+
async function applyTypedOpenCodePick(key, isGeneral, label) {
|
|
464
|
+
const parsed = (0, fallbackChain_1.parseOpenCodeModelLabel)(label);
|
|
465
|
+
if (parsed === null) {
|
|
466
|
+
await replyToThread(key, (0, i18n_1.t)('account.usage'));
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
if (isGeneral) {
|
|
470
|
+
await replyToThread(key, (0, i18n_1.t)('limits.openCodeInTopicOnly'));
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
if (getState().getBinding(key) === null) {
|
|
474
|
+
await replyToThread(key, (0, i18n_1.t)('thread.bind_required'));
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
const outcome = await switchTopicByOperator(key, { backend: 'opencode', providerId: parsed.providerId, modelId: parsed.modelId });
|
|
478
|
+
if (outcome.kind !== 'asked')
|
|
479
|
+
await replyToThread(key, outcome.text);
|
|
480
|
+
}
|
|
379
481
|
// โโ the command โโ
|
|
380
482
|
function registerClaudeAccountCommands() {
|
|
381
483
|
// `/accounts` (hidden alias `/account`) โ bare: the screen. `add <name>` creates a profile and signs it in; `use <name>` switches
|
|
@@ -406,7 +508,13 @@ function createClaudeAccounts(ports) {
|
|
|
406
508
|
await replyToThread(key, (0, i18n_1.t)('account.usage'));
|
|
407
509
|
return;
|
|
408
510
|
}
|
|
409
|
-
|
|
511
|
+
if (name.includes('/')) {
|
|
512
|
+
await applyTypedOpenCodePick(key, isGeneral, rest.join(' ').trim());
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
const confirmation = await applyPick(key, isGeneral, name);
|
|
516
|
+
if (confirmation !== null)
|
|
517
|
+
await replyToThread(key, confirmation);
|
|
410
518
|
return;
|
|
411
519
|
}
|
|
412
520
|
case 'login': {
|
|
@@ -446,88 +554,133 @@ function createClaudeAccounts(ports) {
|
|
|
446
554
|
}
|
|
447
555
|
await withThreadLocale(key, () => run(key, checkIsGeneral(key), (0, callbackMessage_1.getCallbackMessageId)(ctx)));
|
|
448
556
|
}
|
|
449
|
-
/** `answerCbQuery` is capped at 200 characters: a long confirmation goes to the topic instead. */
|
|
450
|
-
async function answerTap(ctx, key, text) {
|
|
451
|
-
if (text.length <= 180) {
|
|
452
|
-
await ctx.answerCbQuery(text);
|
|
453
|
-
return;
|
|
454
|
-
}
|
|
455
|
-
await ctx.answerCbQuery();
|
|
456
|
-
await replyToThread(key, text);
|
|
457
|
-
}
|
|
458
557
|
function registerClaudeAccountCallbacks() {
|
|
459
558
|
bot.action(claudeAccountPickerPlan_1.accountUseCallbackRe, (ctx) => handleTap(ctx, async (key, isGeneral, messageId) => {
|
|
460
559
|
const name = (0, claudeAccountPickerPlan_1.parseAccountCallbackName)(ctx.match[0], claudeAccountPickerPlan_1.accountUseCallbackRe, { allowDefault: true });
|
|
461
560
|
if (name === null) {
|
|
462
|
-
await
|
|
561
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx);
|
|
463
562
|
return;
|
|
464
563
|
}
|
|
465
564
|
const confirmation = await applyPick(key, isGeneral, name);
|
|
466
|
-
|
|
565
|
+
if (confirmation === null)
|
|
566
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx);
|
|
567
|
+
else
|
|
568
|
+
await answerWithWholeText(ctx, key, confirmation);
|
|
467
569
|
await rerenderPicker(key, messageId, isGeneral);
|
|
468
570
|
}));
|
|
469
571
|
bot.action(claudeAccountPickerPlan_1.accountFollowDefaultCallback, (ctx) => handleTap(ctx, async (key, isGeneral, messageId) => {
|
|
470
572
|
if (isGeneral) {
|
|
471
|
-
await
|
|
573
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx);
|
|
472
574
|
return;
|
|
473
575
|
}
|
|
474
|
-
await
|
|
576
|
+
await answerWithWholeText(ctx, key, await applyFollowDefault(key));
|
|
475
577
|
await rerenderPicker(key, messageId, isGeneral);
|
|
476
578
|
}));
|
|
477
579
|
bot.action(claudeAccountPickerPlan_1.accountAddCallback, (ctx) => handleTap(ctx, async (key) => {
|
|
478
580
|
awaitingProfileName.set((0, sessionKey_1.keyToString)(key), 'claudeName');
|
|
479
|
-
await
|
|
581
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx);
|
|
480
582
|
await replyToThread(key, `${(0, i18n_1.t)('account.askName', { max: claudeProfiles_1.claudeProfileNameMaxLength })}\n${(0, i18n_1.t)('login.esc_hint')}`);
|
|
481
583
|
}));
|
|
482
584
|
bot.action(claudeAccountPickerPlan_1.accountAddProviderCallback, (ctx) => handleTap(ctx, async (key) => {
|
|
483
585
|
awaitingProfileName.set((0, sessionKey_1.keyToString)(key), 'providerId');
|
|
484
|
-
await
|
|
586
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx);
|
|
485
587
|
await replyToThread(key, `${(0, i18n_1.t)('accounts.askProvider')}\n${(0, i18n_1.t)('login.esc_hint')}`);
|
|
486
588
|
}));
|
|
487
589
|
// A provider's ยซ๐ยป row โ ask first (a disconnect drops stored credentials), against the snapshot of the
|
|
488
590
|
// message the button sits on: an older screen can never map its index onto a newer list.
|
|
489
591
|
bot.action(claudeAccountPickerPlan_1.accountDisconnectCallbackRe, (ctx) => handleTap(ctx, async (key, isGeneral, messageId) => {
|
|
490
|
-
const provider = messageId === null ? undefined : providerSnapshots.get(messageId)?.[Number(ctx.match[1])];
|
|
592
|
+
const provider = messageId === null ? undefined : providerSnapshots.get((0, callbackMessage_1.buildMessageSnapshotKey)(key, messageId))?.[Number(ctx.match[1])];
|
|
491
593
|
if (messageId === null || provider === undefined) {
|
|
492
|
-
await
|
|
594
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('accounts.stale'));
|
|
493
595
|
await rerenderPicker(key, messageId, isGeneral);
|
|
494
596
|
return;
|
|
495
597
|
}
|
|
496
|
-
await
|
|
598
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx);
|
|
497
599
|
await editThreadMessage(key, messageId, (0, i18n_1.t)('accounts.confirmDisconnect', { provider }), telegraf_1.Markup.inlineKeyboard([
|
|
498
600
|
[telegraf_1.Markup.button.callback((0, i18n_1.t)('accounts.confirmDisconnectButton', { provider }), (0, claudeAccountPickerPlan_1.buildAccountDisconnectConfirmCallback)(Number(ctx.match[1])))],
|
|
499
601
|
[telegraf_1.Markup.button.callback((0, i18n_1.t)('account.backButton'), claudeAccountPickerPlan_1.accountBackCallback)],
|
|
500
602
|
]));
|
|
501
603
|
}));
|
|
502
604
|
bot.action(claudeAccountPickerPlan_1.accountDisconnectConfirmCallbackRe, (ctx) => handleTap(ctx, async (key, isGeneral, messageId) => {
|
|
503
|
-
const provider = messageId === null ? undefined : providerSnapshots.get(messageId)?.[Number(ctx.match[1])];
|
|
605
|
+
const provider = messageId === null ? undefined : providerSnapshots.get((0, callbackMessage_1.buildMessageSnapshotKey)(key, messageId))?.[Number(ctx.match[1])];
|
|
504
606
|
if (messageId === null || provider === undefined) {
|
|
505
|
-
await
|
|
607
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('accounts.stale'));
|
|
506
608
|
await rerenderPicker(key, messageId, isGeneral);
|
|
507
609
|
return;
|
|
508
610
|
}
|
|
509
|
-
await
|
|
611
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx);
|
|
510
612
|
await disconnectOpenCodeProvider(key, provider);
|
|
511
613
|
await rerenderPicker(key, messageId, isGeneral);
|
|
512
614
|
}));
|
|
513
615
|
// A provider's ยซ๐ยป โ connect it again (the method picker); the screen is re-rendered first.
|
|
514
616
|
bot.action(claudeAccountPickerPlan_1.accountReconnectCallbackRe, (ctx) => handleTap(ctx, async (key, isGeneral, messageId) => {
|
|
515
|
-
const provider = messageId === null ? undefined : providerSnapshots.get(messageId)?.[Number(ctx.match[1])];
|
|
617
|
+
const provider = messageId === null ? undefined : providerSnapshots.get((0, callbackMessage_1.buildMessageSnapshotKey)(key, messageId))?.[Number(ctx.match[1])];
|
|
516
618
|
if (messageId === null || provider === undefined) {
|
|
517
|
-
await
|
|
619
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('accounts.stale'));
|
|
518
620
|
await rerenderPicker(key, messageId, isGeneral);
|
|
519
621
|
return;
|
|
520
622
|
}
|
|
521
|
-
await
|
|
623
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx);
|
|
522
624
|
await startOpenCodeConnect(key, provider);
|
|
523
625
|
}));
|
|
626
|
+
// A provider row in a topic โ its model page (a provider with one model is picked at once, unless the topic runs on it);
|
|
627
|
+
// resolved against the snapshot of the message the button sits on, like the disconnect buttons.
|
|
628
|
+
bot.action(claudeAccountPickerPlan_1.accountOpenCodeUseCallbackRe, (ctx) => handleTap(ctx, async (key, isGeneral, messageId) => {
|
|
629
|
+
const provider = messageId === null ? undefined : providerSnapshots.get((0, callbackMessage_1.buildMessageSnapshotKey)(key, messageId))?.[Number(ctx.match[1])];
|
|
630
|
+
const answerStale = async () => {
|
|
631
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('accounts.stale'));
|
|
632
|
+
await rerenderPicker(key, messageId, isGeneral);
|
|
633
|
+
};
|
|
634
|
+
if (messageId === null || provider === undefined) {
|
|
635
|
+
await answerStale();
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
if (isGeneral) {
|
|
639
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('limits.openCodeInTopicOnly'));
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
if (getState().getBinding(key) === null) {
|
|
643
|
+
await answerWithWholeText(ctx, key, (0, i18n_1.t)('thread.bind_required'));
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
const models = (0, fallbackChain_1.listOpenCodeModelsOfProvider)(await listOpenCodeModels(), provider);
|
|
647
|
+
await (0, modelPage_1.handleProviderTap)({
|
|
648
|
+
...buildPickDeps(ctx, key, messageId, isGeneral),
|
|
649
|
+
providerId: provider,
|
|
650
|
+
models,
|
|
651
|
+
rung: getTopicRun(key).rung,
|
|
652
|
+
showPage: () => showProviderModelPage(key, messageId, provider, models, 0),
|
|
653
|
+
answerStale,
|
|
654
|
+
});
|
|
655
|
+
}));
|
|
656
|
+
bot.action(claudeAccountPickerPlan_1.accountOpenCodePageCallbackRe, (ctx) => handleTap(ctx, async (key, isGeneral, messageId) => {
|
|
657
|
+
const page = messageId === null ? undefined : pageSnapshots.get((0, callbackMessage_1.buildMessageSnapshotKey)(key, messageId));
|
|
658
|
+
if (messageId === null || page === undefined) {
|
|
659
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('accounts.stale'));
|
|
660
|
+
await rerenderPicker(key, messageId, isGeneral);
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx);
|
|
664
|
+
await showProviderModelPage(key, messageId, page.providerId, page.models, Number(ctx.match[1]));
|
|
665
|
+
}));
|
|
666
|
+
// A model on the open page: the switch. A refusal stays on the page; anything else returns to the screen, its โ moved.
|
|
667
|
+
bot.action(claudeAccountPickerPlan_1.accountOpenCodeModelCallbackRe, (ctx) => handleTap(ctx, async (key, isGeneral, messageId) => {
|
|
668
|
+
const page = messageId === null ? undefined : pageSnapshots.get((0, callbackMessage_1.buildMessageSnapshotKey)(key, messageId));
|
|
669
|
+
const modelId = page?.models[Number(ctx.match[1])];
|
|
670
|
+
if (messageId === null || page === undefined || modelId === undefined) {
|
|
671
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('accounts.stale'));
|
|
672
|
+
await rerenderPicker(key, messageId, isGeneral);
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
await (0, modelPage_1.handleModelPick)(buildPickDeps(ctx, key, messageId, isGeneral), { backend: 'opencode', providerId: page.providerId, modelId });
|
|
676
|
+
}));
|
|
524
677
|
bot.action(claudeAccountPickerPlan_1.accountLoginMenuCallback, (ctx) => handleTap(ctx, async (key, _isGeneral, messageId) => {
|
|
525
|
-
await
|
|
678
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx);
|
|
526
679
|
if (messageId !== null)
|
|
527
680
|
await editThreadMessage(key, messageId, (0, i18n_1.t)('account.pickLogin'), buildProfileChoiceKeyboard(claudeAccountPickerPlan_1.buildAccountLoginCallback, true));
|
|
528
681
|
}));
|
|
529
682
|
bot.action(claudeAccountPickerPlan_1.accountRemoveMenuCallback, (ctx) => handleTap(ctx, async (key, _isGeneral, messageId) => {
|
|
530
|
-
await
|
|
683
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx);
|
|
531
684
|
if (Object.keys(getState().getClaudeProfileRecords()).length === 0) {
|
|
532
685
|
await replyToThread(key, (0, i18n_1.t)('account.nothingToRemove'));
|
|
533
686
|
return;
|
|
@@ -536,16 +689,16 @@ function createClaudeAccounts(ports) {
|
|
|
536
689
|
await editThreadMessage(key, messageId, (0, i18n_1.t)('account.pickRemove'), buildProfileChoiceKeyboard(claudeAccountPickerPlan_1.buildAccountRemoveCallback, false));
|
|
537
690
|
}));
|
|
538
691
|
bot.action(claudeAccountPickerPlan_1.accountBackCallback, (ctx) => handleTap(ctx, async (key, isGeneral, messageId) => {
|
|
539
|
-
await
|
|
692
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx);
|
|
540
693
|
await rerenderPicker(key, messageId, isGeneral);
|
|
541
694
|
}));
|
|
542
695
|
bot.action(claudeAccountPickerPlan_1.accountLoginCallbackRe, (ctx) => handleTap(ctx, async (key, isGeneral, messageId) => {
|
|
543
696
|
const name = (0, claudeAccountPickerPlan_1.parseAccountCallbackName)(ctx.match[0], claudeAccountPickerPlan_1.accountLoginCallbackRe, { allowDefault: true });
|
|
544
697
|
if (name === null) {
|
|
545
|
-
await
|
|
698
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx);
|
|
546
699
|
return;
|
|
547
700
|
}
|
|
548
|
-
await
|
|
701
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx);
|
|
549
702
|
await rerenderPicker(key, messageId, isGeneral); // the sub-picker is consumed back into the main picker
|
|
550
703
|
const message = await loginProfile(key, name);
|
|
551
704
|
if (message)
|
|
@@ -554,10 +707,10 @@ function createClaudeAccounts(ports) {
|
|
|
554
707
|
bot.action(claudeAccountPickerPlan_1.accountRemoveCallbackRe, (ctx) => handleTap(ctx, async (key, _isGeneral, messageId) => {
|
|
555
708
|
const name = (0, claudeAccountPickerPlan_1.parseAccountCallbackName)(ctx.match[0], claudeAccountPickerPlan_1.accountRemoveCallbackRe, { allowDefault: true });
|
|
556
709
|
if (name === null || !checkIsKnownProfile(name)) {
|
|
557
|
-
await
|
|
710
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx, (0, i18n_1.t)('account.unknown', { name: name ?? '?' }));
|
|
558
711
|
return;
|
|
559
712
|
}
|
|
560
|
-
await
|
|
713
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx);
|
|
561
714
|
const confirmation = buildRemoveConfirmation(name);
|
|
562
715
|
if (messageId !== null)
|
|
563
716
|
await editThreadMessage(key, messageId, confirmation.text, confirmation.keyboard);
|
|
@@ -565,16 +718,16 @@ function createClaudeAccounts(ports) {
|
|
|
565
718
|
bot.action(claudeAccountPickerPlan_1.accountRemoveConfirmCallbackRe, (ctx) => handleTap(ctx, async (key, isGeneral, messageId) => {
|
|
566
719
|
const name = (0, claudeAccountPickerPlan_1.parseAccountCallbackName)(ctx.match[0], claudeAccountPickerPlan_1.accountRemoveConfirmCallbackRe, { allowDefault: true });
|
|
567
720
|
if (name === null) {
|
|
568
|
-
await
|
|
721
|
+
await (0, callbackToast_1.answerCallbackQuerySafely)(ctx);
|
|
569
722
|
return;
|
|
570
723
|
}
|
|
571
724
|
const result = await removeProfile(name);
|
|
572
|
-
await
|
|
725
|
+
await answerWithWholeText(ctx, key, result);
|
|
573
726
|
await rerenderPicker(key, messageId, isGeneral);
|
|
574
727
|
}));
|
|
575
728
|
for (const [callback, enabled] of [[claudeAccountPickerPlan_1.accountAutoSwitchOnCallback, true], [claudeAccountPickerPlan_1.accountAutoSwitchOffCallback, false]]) {
|
|
576
729
|
bot.action(callback, (ctx) => handleTap(ctx, async (key, isGeneral, messageId) => {
|
|
577
|
-
await
|
|
730
|
+
await answerWithWholeText(ctx, key, await applyAutoSwitch(key, isGeneral, enabled));
|
|
578
731
|
await rerenderPicker(key, messageId, isGeneral);
|
|
579
732
|
}));
|
|
580
733
|
}
|
|
@@ -585,6 +738,7 @@ function createClaudeAccounts(ports) {
|
|
|
585
738
|
checkIsAwaitingProfileName,
|
|
586
739
|
cancelProfileNameCapture,
|
|
587
740
|
submitProfileName,
|
|
741
|
+
pickClaudeAccount: applyPick,
|
|
588
742
|
onClaudeProfileAuthStatus,
|
|
589
743
|
};
|
|
590
744
|
}
|