@grinev/opencode-telegram-bot 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -9
- package/dist/agent/manager.js +10 -14
- package/dist/bot/commands/commands.js +379 -0
- package/dist/bot/commands/definitions.js +1 -0
- package/dist/bot/commands/projects.js +102 -18
- package/dist/bot/commands/status.js +20 -1
- package/dist/bot/handlers/agent.js +20 -10
- package/dist/bot/handlers/document.js +65 -0
- package/dist/bot/index.js +27 -6
- package/dist/bot/message-patterns.js +2 -1
- package/dist/bot/utils/file-download.js +16 -0
- package/dist/i18n/de.js +25 -0
- package/dist/i18n/en.js +25 -0
- package/dist/i18n/es.js +25 -0
- package/dist/i18n/ru.js +25 -0
- package/dist/i18n/zh.js +25 -0
- package/dist/model/types.js +4 -6
- package/package.json +1 -1
|
@@ -6,6 +6,8 @@ import { getAgentDisplayName } from "../../agent/types.js";
|
|
|
6
6
|
import { fetchCurrentModel } from "../../model/manager.js";
|
|
7
7
|
import { formatModelForDisplay } from "../../model/types.js";
|
|
8
8
|
import { processManager } from "../../process/manager.js";
|
|
9
|
+
import { keyboardManager } from "../../keyboard/manager.js";
|
|
10
|
+
import { pinnedMessageManager } from "../../pinned/manager.js";
|
|
9
11
|
import { logger } from "../../utils/logger.js";
|
|
10
12
|
import { t } from "../../i18n/index.js";
|
|
11
13
|
import { sendMessageWithMarkdownFallback } from "../utils/send-with-markdown-fallback.js";
|
|
@@ -59,16 +61,33 @@ export async function statusCommand(ctx) {
|
|
|
59
61
|
message += `\n${t("status.session_not_selected")}\n`;
|
|
60
62
|
message += t("status.session_hint");
|
|
61
63
|
}
|
|
64
|
+
if (ctx.chat) {
|
|
65
|
+
if (!pinnedMessageManager.isInitialized()) {
|
|
66
|
+
pinnedMessageManager.initialize(ctx.api, ctx.chat.id);
|
|
67
|
+
}
|
|
68
|
+
// Fetch context limit if not yet loaded (e.g. fresh bot start)
|
|
69
|
+
if (pinnedMessageManager.getContextLimit() === 0) {
|
|
70
|
+
await pinnedMessageManager.refreshContextLimit();
|
|
71
|
+
}
|
|
72
|
+
keyboardManager.initialize(ctx.api, ctx.chat.id);
|
|
73
|
+
}
|
|
74
|
+
// Sync current context (tokens used + limit) into keyboard state
|
|
75
|
+
const contextInfo = pinnedMessageManager.getContextInfo();
|
|
76
|
+
if (contextInfo) {
|
|
77
|
+
keyboardManager.updateContext(contextInfo.tokensUsed, contextInfo.tokensLimit);
|
|
78
|
+
}
|
|
79
|
+
const keyboard = keyboardManager.getKeyboard();
|
|
62
80
|
if (ctx.chat) {
|
|
63
81
|
await sendMessageWithMarkdownFallback({
|
|
64
82
|
api: ctx.api,
|
|
65
83
|
chatId: ctx.chat.id,
|
|
66
84
|
text: message,
|
|
85
|
+
options: { reply_markup: keyboard },
|
|
67
86
|
parseMode: "Markdown",
|
|
68
87
|
});
|
|
69
88
|
}
|
|
70
89
|
else {
|
|
71
|
-
await ctx.reply(message);
|
|
90
|
+
await ctx.reply(message, { reply_markup: keyboard });
|
|
72
91
|
}
|
|
73
92
|
}
|
|
74
93
|
catch (error) {
|
|
@@ -95,14 +95,24 @@ export async function buildAgentSelectionMenu(currentAgent) {
|
|
|
95
95
|
* @param ctx grammY context
|
|
96
96
|
*/
|
|
97
97
|
export async function showAgentSelectionMenu(ctx) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
text
|
|
106
|
-
|
|
107
|
-
|
|
98
|
+
try {
|
|
99
|
+
const currentAgent = await fetchCurrentAgent();
|
|
100
|
+
const keyboard = await buildAgentSelectionMenu(currentAgent);
|
|
101
|
+
if (keyboard.inline_keyboard.length === 0) {
|
|
102
|
+
await ctx.reply(t("agent.menu.empty"));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const text = currentAgent
|
|
106
|
+
? t("agent.menu.current", { name: getAgentDisplayName(currentAgent) })
|
|
107
|
+
: t("agent.menu.select");
|
|
108
|
+
await replyWithInlineMenu(ctx, {
|
|
109
|
+
menuKind: "agent",
|
|
110
|
+
text,
|
|
111
|
+
keyboard,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
logger.error("[AgentHandler] Error showing agent menu:", err);
|
|
116
|
+
await ctx.reply(t("agent.menu.error"));
|
|
117
|
+
}
|
|
108
118
|
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { config } from "../../config.js";
|
|
2
|
+
import { processUserPrompt } from "./prompt.js";
|
|
3
|
+
import { downloadTelegramFile, toDataUri, isTextMimeType, isFileSizeAllowed, } from "../utils/file-download.js";
|
|
4
|
+
import { getModelCapabilities, supportsInput } from "../../model/capabilities.js";
|
|
5
|
+
import { getStoredModel } from "../../model/manager.js";
|
|
6
|
+
import { logger } from "../../utils/logger.js";
|
|
7
|
+
import { t } from "../../i18n/index.js";
|
|
8
|
+
export async function handleDocumentMessage(ctx, deps) {
|
|
9
|
+
const downloadFile = deps.downloadFile ?? downloadTelegramFile;
|
|
10
|
+
const getCapabilities = deps.getModelCapabilities ?? getModelCapabilities;
|
|
11
|
+
const getStored = deps.getStoredModel ?? getStoredModel;
|
|
12
|
+
const processPrompt = deps.processPrompt ?? processUserPrompt;
|
|
13
|
+
const doc = ctx.message?.document;
|
|
14
|
+
if (!doc) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const caption = ctx.message.caption || "";
|
|
18
|
+
const mimeType = doc.mime_type || "";
|
|
19
|
+
const filename = doc.file_name || "document";
|
|
20
|
+
try {
|
|
21
|
+
if (isTextMimeType(mimeType)) {
|
|
22
|
+
if (!isFileSizeAllowed(doc.file_size, config.files.maxFileSizeKb)) {
|
|
23
|
+
logger.warn(`[Document] Text file too large: ${filename} (${doc.file_size} bytes > ${config.files.maxFileSizeKb}KB)`);
|
|
24
|
+
await ctx.reply(t("bot.text_file_too_large", { maxSizeKb: String(config.files.maxFileSizeKb) }));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
await ctx.reply(t("bot.file_downloading"));
|
|
28
|
+
const downloadedFile = await downloadFile(ctx.api, doc.file_id);
|
|
29
|
+
const textContent = downloadedFile.buffer.toString("utf-8");
|
|
30
|
+
const promptWithFile = `--- Content of ${filename} ---\n${textContent}\n--- End of file ---\n\n${caption}`;
|
|
31
|
+
logger.info(`[Document] Sending text file (${downloadedFile.buffer.length} bytes, ${filename}) as prompt`);
|
|
32
|
+
await processPrompt(ctx, promptWithFile, deps);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (mimeType === "application/pdf") {
|
|
36
|
+
const storedModel = getStored();
|
|
37
|
+
const capabilities = await getCapabilities(storedModel.providerID, storedModel.modelID);
|
|
38
|
+
if (!supportsInput(capabilities, "pdf")) {
|
|
39
|
+
logger.warn(`[Document] Model ${storedModel.providerID}/${storedModel.modelID} doesn't support PDF input`);
|
|
40
|
+
await ctx.reply(t("bot.model_no_pdf"));
|
|
41
|
+
if (caption.trim().length > 0) {
|
|
42
|
+
await processPrompt(ctx, caption, deps);
|
|
43
|
+
}
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
await ctx.reply(t("bot.file_downloading"));
|
|
47
|
+
const downloadedFile = await downloadFile(ctx.api, doc.file_id);
|
|
48
|
+
const dataUri = toDataUri(downloadedFile.buffer, mimeType);
|
|
49
|
+
const filePart = {
|
|
50
|
+
type: "file",
|
|
51
|
+
mime: mimeType,
|
|
52
|
+
filename: filename,
|
|
53
|
+
url: dataUri,
|
|
54
|
+
};
|
|
55
|
+
logger.info(`[Document] Sending PDF (${downloadedFile.buffer.length} bytes, ${filename}) with prompt`);
|
|
56
|
+
await processPrompt(ctx, caption, deps, [filePart]);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
logger.debug(`[Document] Unsupported document MIME type: ${mimeType}, ignoring`);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
logger.error("[Document] Error handling document message:", err);
|
|
63
|
+
await ctx.reply(t("bot.file_download_error"));
|
|
64
|
+
}
|
|
65
|
+
}
|
package/dist/bot/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { BOT_COMMANDS } from "./commands/definitions.js";
|
|
|
12
12
|
import { startCommand } from "./commands/start.js";
|
|
13
13
|
import { helpCommand } from "./commands/help.js";
|
|
14
14
|
import { statusCommand } from "./commands/status.js";
|
|
15
|
-
import { MODEL_BUTTON_TEXT_PATTERN, VARIANT_BUTTON_TEXT_PATTERN } from "./message-patterns.js";
|
|
15
|
+
import { AGENT_MODE_BUTTON_TEXT_PATTERN, MODEL_BUTTON_TEXT_PATTERN, VARIANT_BUTTON_TEXT_PATTERN, } from "./message-patterns.js";
|
|
16
16
|
import { sessionsCommand, handleSessionSelect } from "./commands/sessions.js";
|
|
17
17
|
import { newCommand } from "./commands/new.js";
|
|
18
18
|
import { projectsCommand, handleProjectSelect } from "./commands/projects.js";
|
|
@@ -20,6 +20,7 @@ import { stopCommand } from "./commands/stop.js";
|
|
|
20
20
|
import { opencodeStartCommand } from "./commands/opencode-start.js";
|
|
21
21
|
import { opencodeStopCommand } from "./commands/opencode-stop.js";
|
|
22
22
|
import { renameCommand, handleRenameCancel, handleRenameTextAnswer } from "./commands/rename.js";
|
|
23
|
+
import { commandsCommand, handleCommandsCallback, handleCommandTextArguments, } from "./commands/commands.js";
|
|
23
24
|
import { handleQuestionCallback, showCurrentQuestion, handleQuestionTextAnswer, } from "./handlers/question.js";
|
|
24
25
|
import { handlePermissionCallback, showPermissionRequest } from "./handlers/permission.js";
|
|
25
26
|
import { handleAgentSelect, showAgentSelectionMenu } from "./handlers/agent.js";
|
|
@@ -43,6 +44,7 @@ import { pinnedMessageManager } from "../pinned/manager.js";
|
|
|
43
44
|
import { t } from "../i18n/index.js";
|
|
44
45
|
import { processUserPrompt } from "./handlers/prompt.js";
|
|
45
46
|
import { handleVoiceMessage } from "./handlers/voice.js";
|
|
47
|
+
import { handleDocumentMessage } from "./handlers/document.js";
|
|
46
48
|
import { downloadTelegramFile, toDataUri } from "./utils/file-download.js";
|
|
47
49
|
import { sendMessageWithMarkdownFallback } from "./utils/send-with-markdown-fallback.js";
|
|
48
50
|
import { getModelCapabilities, supportsInput } from "../model/capabilities.js";
|
|
@@ -456,10 +458,15 @@ export function createBot() {
|
|
|
456
458
|
bot.command("new", newCommand);
|
|
457
459
|
bot.command("stop", stopCommand);
|
|
458
460
|
bot.command("rename", renameCommand);
|
|
461
|
+
bot.command("commands", commandsCommand);
|
|
459
462
|
bot.on("message:text", unknownCommandMiddleware);
|
|
460
463
|
bot.on("callback_query:data", async (ctx) => {
|
|
461
464
|
logger.debug(`[Bot] Received callback_query:data: ${ctx.callbackQuery?.data}`);
|
|
462
465
|
logger.debug(`[Bot] Callback context: from=${ctx.from?.id}, chat=${ctx.chat?.id}`);
|
|
466
|
+
if (ctx.chat) {
|
|
467
|
+
botInstance = bot;
|
|
468
|
+
chatIdInstance = ctx.chat.id;
|
|
469
|
+
}
|
|
463
470
|
try {
|
|
464
471
|
const handledInlineCancel = await handleInlineMenuCancel(ctx);
|
|
465
472
|
const handledSession = await handleSessionSelect(ctx);
|
|
@@ -471,7 +478,8 @@ export function createBot() {
|
|
|
471
478
|
const handledVariant = await handleVariantSelect(ctx);
|
|
472
479
|
const handledCompactConfirm = await handleCompactConfirm(ctx);
|
|
473
480
|
const handledRenameCancel = await handleRenameCancel(ctx);
|
|
474
|
-
|
|
481
|
+
const handledCommands = await handleCommandsCallback(ctx, { bot, ensureEventSubscription });
|
|
482
|
+
logger.debug(`[Bot] Callback handled: inlineCancel=${handledInlineCancel}, session=${handledSession}, project=${handledProject}, question=${handledQuestion}, permission=${handledPermission}, agent=${handledAgent}, model=${handledModel}, variant=${handledVariant}, compactConfirm=${handledCompactConfirm}, rename=${handledRenameCancel}, commands=${handledCommands}`);
|
|
475
483
|
if (!handledInlineCancel &&
|
|
476
484
|
!handledSession &&
|
|
477
485
|
!handledProject &&
|
|
@@ -481,7 +489,8 @@ export function createBot() {
|
|
|
481
489
|
!handledModel &&
|
|
482
490
|
!handledVariant &&
|
|
483
491
|
!handledCompactConfirm &&
|
|
484
|
-
!handledRenameCancel
|
|
492
|
+
!handledRenameCancel &&
|
|
493
|
+
!handledCommands) {
|
|
485
494
|
logger.debug("Unknown callback query:", ctx.callbackQuery?.data);
|
|
486
495
|
await ctx.answerCallbackQuery({ text: t("callback.unknown_command") });
|
|
487
496
|
}
|
|
@@ -493,7 +502,7 @@ export function createBot() {
|
|
|
493
502
|
}
|
|
494
503
|
});
|
|
495
504
|
// Handle Reply Keyboard button press (agent mode indicator)
|
|
496
|
-
bot.hears(
|
|
505
|
+
bot.hears(AGENT_MODE_BUTTON_TEXT_PATTERN, async (ctx) => {
|
|
497
506
|
logger.debug(`[Bot] Agent mode button pressed: ${ctx.message?.text}`);
|
|
498
507
|
try {
|
|
499
508
|
if (await blockMenuWhileInteractionActive(ctx)) {
|
|
@@ -645,11 +654,21 @@ export function createBot() {
|
|
|
645
654
|
await ctx.reply(t("bot.photo_download_error"));
|
|
646
655
|
}
|
|
647
656
|
});
|
|
657
|
+
// Document message handler (PDF and text files)
|
|
658
|
+
bot.on("message:document", async (ctx) => {
|
|
659
|
+
logger.debug(`[Bot] Received document message, chatId=${ctx.chat.id}`);
|
|
660
|
+
botInstance = bot;
|
|
661
|
+
chatIdInstance = ctx.chat.id;
|
|
662
|
+
const deps = { bot, ensureEventSubscription };
|
|
663
|
+
await handleDocumentMessage(ctx, deps);
|
|
664
|
+
});
|
|
648
665
|
bot.on("message:text", async (ctx) => {
|
|
649
666
|
const text = ctx.message?.text;
|
|
650
667
|
if (!text) {
|
|
651
668
|
return;
|
|
652
669
|
}
|
|
670
|
+
botInstance = bot;
|
|
671
|
+
chatIdInstance = ctx.chat.id;
|
|
653
672
|
if (text.startsWith("/")) {
|
|
654
673
|
return;
|
|
655
674
|
}
|
|
@@ -661,9 +680,11 @@ export function createBot() {
|
|
|
661
680
|
if (handledRename) {
|
|
662
681
|
return;
|
|
663
682
|
}
|
|
664
|
-
botInstance = bot;
|
|
665
|
-
chatIdInstance = ctx.chat.id;
|
|
666
683
|
const promptDeps = { bot, ensureEventSubscription };
|
|
684
|
+
const handledCommandArgs = await handleCommandTextArguments(ctx, promptDeps);
|
|
685
|
+
if (handledCommandArgs) {
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
667
688
|
await processUserPrompt(ctx, text, promptDeps);
|
|
668
689
|
logger.debug("[Bot] message:text handler completed (prompt sent in background)");
|
|
669
690
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const AGENT_MODE_BUTTON_TEXT_PATTERN = /^(📋|🛠️|💬|🔍|📝|📄|📦|🤖)\s.+\sMode$/;
|
|
2
|
+
export const MODEL_BUTTON_TEXT_PATTERN = /^🤖\s(?!.*\sMode$)[\s\S]+$/;
|
|
2
3
|
// Keep support for both legacy "💭" and current "💡" prefix.
|
|
3
4
|
export const VARIANT_BUTTON_TEXT_PATTERN = /^(💡|💭)\s.+$/;
|
|
@@ -73,3 +73,19 @@ export function formatFileSize(bytes) {
|
|
|
73
73
|
}
|
|
74
74
|
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
75
75
|
}
|
|
76
|
+
const APPLICATION_TEXT_MIME_TYPES = new Set([
|
|
77
|
+
"application/json",
|
|
78
|
+
"application/xml",
|
|
79
|
+
"application/javascript",
|
|
80
|
+
"application/x-yaml",
|
|
81
|
+
"application/sql",
|
|
82
|
+
]);
|
|
83
|
+
export function isTextMimeType(mimeType) {
|
|
84
|
+
if (!mimeType) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
if (mimeType.startsWith("text/")) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
return APPLICATION_TEXT_MIME_TYPES.has(mimeType);
|
|
91
|
+
}
|
package/dist/i18n/de.js
CHANGED
|
@@ -4,6 +4,7 @@ export const de = {
|
|
|
4
4
|
"cmd.description.stop": "Aktuelle Aktion stoppen",
|
|
5
5
|
"cmd.description.sessions": "Sitzungen auflisten",
|
|
6
6
|
"cmd.description.projects": "Projekte auflisten",
|
|
7
|
+
"cmd.description.commands": "Benutzerdefinierte Befehle",
|
|
7
8
|
"cmd.description.opencode_start": "OpenCode-Server starten",
|
|
8
9
|
"cmd.description.opencode_stop": "OpenCode-Server stoppen",
|
|
9
10
|
"cmd.description.help": "Hilfe",
|
|
@@ -48,6 +49,11 @@ export const de = {
|
|
|
48
49
|
"bot.photo_model_no_image": "⚠️ Das aktuelle Modell unterstützt keine Bildeingabe. Sende nur Text.",
|
|
49
50
|
"bot.photo_download_error": "🔴 Foto konnte nicht heruntergeladen werden",
|
|
50
51
|
"bot.photo_no_caption": "💡 Tipp: Füge eine Bildunterschrift hinzu, um zu beschreiben, was du mit diesem Foto tun möchtest.",
|
|
52
|
+
"bot.file_downloading": "⏳ Lade Datei herunter...",
|
|
53
|
+
"bot.file_too_large": "⚠️ Datei ist zu groß (max. {maxSizeMb}MB)",
|
|
54
|
+
"bot.file_download_error": "🔴 Datei konnte nicht heruntergeladen werden",
|
|
55
|
+
"bot.model_no_pdf": "⚠️ Das aktuelle Modell unterstützt keine PDF-Eingabe. Sende nur Text.",
|
|
56
|
+
"bot.text_file_too_large": "⚠️ Textdatei ist zu groß (max. {maxSizeKb}KB)",
|
|
51
57
|
"status.header_running": "🟢 **OpenCode-Server läuft**",
|
|
52
58
|
"status.health.healthy": "OK",
|
|
53
59
|
"status.health.unhealthy": "Nicht OK",
|
|
@@ -70,7 +76,11 @@ export const de = {
|
|
|
70
76
|
"projects.empty": "📭 Keine Projekte gefunden.\n\nÖffne ein Verzeichnis in OpenCode und erstelle mindestens eine Sitzung, dann erscheint es hier.",
|
|
71
77
|
"projects.select": "Projekt auswählen:",
|
|
72
78
|
"projects.select_with_current": "Projekt auswählen:\n\nAktuell: 🏗 {project}",
|
|
79
|
+
"projects.page_indicator": "Seite {current}/{total}",
|
|
80
|
+
"projects.prev_page": "⬅️ Zurück",
|
|
81
|
+
"projects.next_page": "Weiter ➡️",
|
|
73
82
|
"projects.fetch_error": "🔴 OpenCode-Server ist nicht verfügbar oder beim Laden der Projekte ist ein Fehler aufgetreten.",
|
|
83
|
+
"projects.page_load_error": "Diese Seite konnte nicht geladen werden. Bitte versuche es erneut.",
|
|
74
84
|
"projects.selected": "✅ Projekt ausgewählt: {project}\n\n📋 Sitzung wurde zurückgesetzt. Nutze /sessions oder /new für dieses Projekt.",
|
|
75
85
|
"projects.select_error": "🔴 Projekt konnte nicht ausgewählt werden.",
|
|
76
86
|
"sessions.project_not_selected": "🏗 Projekt ist nicht ausgewählt.\n\nWähle zuerst ein Projekt mit /projects.",
|
|
@@ -120,6 +130,8 @@ export const de = {
|
|
|
120
130
|
"agent.change_error_callback": "Modus konnte nicht geändert werden",
|
|
121
131
|
"agent.menu.current": "Aktueller Modus: {name}\n\nModus auswählen:",
|
|
122
132
|
"agent.menu.select": "Arbeitsmodus auswählen:",
|
|
133
|
+
"agent.menu.empty": "⚠️ Keine verfügbaren Agenten",
|
|
134
|
+
"agent.menu.error": "🔴 Agentenliste konnte nicht geladen werden",
|
|
123
135
|
"model.changed_callback": "Modell geändert: {name}",
|
|
124
136
|
"model.changed_message": "✅ Modell geändert zu: {name}",
|
|
125
137
|
"model.change_error_callback": "Modell konnte nicht geändert werden",
|
|
@@ -232,6 +244,19 @@ export const de = {
|
|
|
232
244
|
"rename.blocked.expected_name": "⚠️ Sende den neuen Sitzungsnamen als Text oder tippe in der Umbenennen-Nachricht auf Abbrechen.",
|
|
233
245
|
"rename.blocked.command_not_allowed": "⚠️ Dieser Befehl ist nicht verfügbar, solange beim Umbenennen auf einen neuen Namen gewartet wird.",
|
|
234
246
|
"rename.button.cancel": "❌ Abbrechen",
|
|
247
|
+
"commands.select": "Wähle einen OpenCode-Befehl:",
|
|
248
|
+
"commands.empty": "📭 Für dieses Projekt sind keine OpenCode-Befehle verfügbar.",
|
|
249
|
+
"commands.fetch_error": "🔴 OpenCode-Befehle konnten nicht geladen werden.",
|
|
250
|
+
"commands.no_description": "Keine Beschreibung",
|
|
251
|
+
"commands.button.execute": "✅ Ausführen",
|
|
252
|
+
"commands.button.cancel": "❌ Abbrechen",
|
|
253
|
+
"commands.confirm": "Bestätige die Ausführung des Befehls {command}. Für die Ausführung mit Argumenten sende die Argumente als Nachricht.",
|
|
254
|
+
"commands.inactive_callback": "Dieses Befehlsmenü ist inaktiv",
|
|
255
|
+
"commands.cancelled_callback": "Abgebrochen",
|
|
256
|
+
"commands.execute_callback": "Befehl wird ausgeführt...",
|
|
257
|
+
"commands.executing_prefix": "⚡ Befehl wird ausgeführt:",
|
|
258
|
+
"commands.arguments_empty": "⚠️ Argumente dürfen nicht leer sein. Sende Text oder tippe auf Ausführen.",
|
|
259
|
+
"commands.execute_error": "🔴 OpenCode-Befehl konnte nicht ausgeführt werden.",
|
|
235
260
|
"cmd.description.rename": "Aktuelle Sitzung umbenennen",
|
|
236
261
|
"cli.usage": "Verwendung:\n opencode-telegram [start] [--mode sources|installed]\n opencode-telegram status\n opencode-telegram stop\n opencode-telegram config\n\nHinweise:\n - Ohne Befehl wird standardmäßig `start` verwendet\n - `--mode` wird derzeit nur für `start` unterstützt",
|
|
237
262
|
"cli.placeholder.status": "Befehl `status` ist derzeit ein Platzhalter. Echte Statusprüfungen werden in der Service-Schicht hinzugefügt (Phase 5).",
|
package/dist/i18n/en.js
CHANGED
|
@@ -4,6 +4,7 @@ export const en = {
|
|
|
4
4
|
"cmd.description.stop": "Stop current action",
|
|
5
5
|
"cmd.description.sessions": "List sessions",
|
|
6
6
|
"cmd.description.projects": "List projects",
|
|
7
|
+
"cmd.description.commands": "Custom commands",
|
|
7
8
|
"cmd.description.opencode_start": "Start OpenCode server",
|
|
8
9
|
"cmd.description.opencode_stop": "Stop OpenCode server",
|
|
9
10
|
"cmd.description.help": "Help",
|
|
@@ -48,6 +49,11 @@ export const en = {
|
|
|
48
49
|
"bot.photo_model_no_image": "⚠️ Current model doesn't support image input. Sending text only.",
|
|
49
50
|
"bot.photo_download_error": "🔴 Failed to download photo",
|
|
50
51
|
"bot.photo_no_caption": "💡 Tip: Add a caption to describe what you want to do with this photo.",
|
|
52
|
+
"bot.file_downloading": "⏳ Downloading file...",
|
|
53
|
+
"bot.file_too_large": "⚠️ File is too large (max {maxSizeMb}MB)",
|
|
54
|
+
"bot.file_download_error": "🔴 Failed to download file",
|
|
55
|
+
"bot.model_no_pdf": "⚠️ Current model doesn't support PDF input. Sending text only.",
|
|
56
|
+
"bot.text_file_too_large": "⚠️ Text file is too large (max {maxSizeKb}KB)",
|
|
51
57
|
"status.header_running": "🟢 **OpenCode Server is running**",
|
|
52
58
|
"status.health.healthy": "Healthy",
|
|
53
59
|
"status.health.unhealthy": "Unhealthy",
|
|
@@ -70,7 +76,11 @@ export const en = {
|
|
|
70
76
|
"projects.empty": "📭 No projects found.\n\nOpen a directory in OpenCode and create at least one session, then it will appear here.",
|
|
71
77
|
"projects.select": "Select a project:",
|
|
72
78
|
"projects.select_with_current": "Select a project:\n\nCurrent: 🏗 {project}",
|
|
79
|
+
"projects.page_indicator": "Page {current}/{total}",
|
|
80
|
+
"projects.prev_page": "⬅️ Previous",
|
|
81
|
+
"projects.next_page": "Next ➡️",
|
|
73
82
|
"projects.fetch_error": "🔴 OpenCode Server is unavailable or an error occurred while loading projects.",
|
|
83
|
+
"projects.page_load_error": "Cannot load this page. Please try again.",
|
|
74
84
|
"projects.selected": "✅ Project selected: {project}\n\n📋 Session was reset. Use /sessions or /new for this project.",
|
|
75
85
|
"projects.select_error": "🔴 Failed to select project.",
|
|
76
86
|
"sessions.project_not_selected": "🏗 Project is not selected.\n\nFirst select a project with /projects.",
|
|
@@ -120,6 +130,8 @@ export const en = {
|
|
|
120
130
|
"agent.change_error_callback": "Failed to change mode",
|
|
121
131
|
"agent.menu.current": "Current mode: {name}\n\nSelect mode:",
|
|
122
132
|
"agent.menu.select": "Select work mode:",
|
|
133
|
+
"agent.menu.empty": "⚠️ No available agents",
|
|
134
|
+
"agent.menu.error": "🔴 Failed to get agents list",
|
|
123
135
|
"model.changed_callback": "Model changed: {name}",
|
|
124
136
|
"model.changed_message": "✅ Model changed to: {name}",
|
|
125
137
|
"model.change_error_callback": "Failed to change model",
|
|
@@ -232,6 +244,19 @@ export const en = {
|
|
|
232
244
|
"rename.blocked.expected_name": "⚠️ Enter a new session name as text or tap Cancel in rename message.",
|
|
233
245
|
"rename.blocked.command_not_allowed": "⚠️ This command is not available while rename is waiting for a new name.",
|
|
234
246
|
"rename.button.cancel": "❌ Cancel",
|
|
247
|
+
"commands.select": "Choose an OpenCode command:",
|
|
248
|
+
"commands.empty": "📭 No OpenCode commands are available for this project.",
|
|
249
|
+
"commands.fetch_error": "🔴 Failed to load OpenCode commands.",
|
|
250
|
+
"commands.no_description": "No description",
|
|
251
|
+
"commands.button.execute": "✅ Execute",
|
|
252
|
+
"commands.button.cancel": "❌ Cancel",
|
|
253
|
+
"commands.confirm": "Confirm execution of command {command}. To run it with arguments, send the arguments as a message.",
|
|
254
|
+
"commands.inactive_callback": "This command menu is inactive",
|
|
255
|
+
"commands.cancelled_callback": "Cancelled",
|
|
256
|
+
"commands.execute_callback": "Executing command...",
|
|
257
|
+
"commands.executing_prefix": "⚡ Executing command:",
|
|
258
|
+
"commands.arguments_empty": "⚠️ Arguments cannot be empty. Send text or tap Execute.",
|
|
259
|
+
"commands.execute_error": "🔴 Failed to execute OpenCode command.",
|
|
235
260
|
"cmd.description.rename": "Rename current session",
|
|
236
261
|
"cli.usage": "Usage:\n opencode-telegram [start] [--mode sources|installed]\n opencode-telegram status\n opencode-telegram stop\n opencode-telegram config\n\nNotes:\n - No command defaults to `start`\n - `--mode` is currently supported for `start` only",
|
|
237
262
|
"cli.placeholder.status": "Command `status` is currently a placeholder. Real status checks will be added in service layer (Phase 5).",
|
package/dist/i18n/es.js
CHANGED
|
@@ -4,6 +4,7 @@ export const es = {
|
|
|
4
4
|
"cmd.description.stop": "Detener la acción actual",
|
|
5
5
|
"cmd.description.sessions": "Listar sesiones",
|
|
6
6
|
"cmd.description.projects": "Listar proyectos",
|
|
7
|
+
"cmd.description.commands": "Comandos personalizados",
|
|
7
8
|
"cmd.description.opencode_start": "Iniciar servidor OpenCode",
|
|
8
9
|
"cmd.description.opencode_stop": "Detener servidor OpenCode",
|
|
9
10
|
"cmd.description.help": "Ayuda",
|
|
@@ -48,6 +49,11 @@ export const es = {
|
|
|
48
49
|
"bot.photo_model_no_image": "⚠️ El modelo actual no admite entrada de imagen. Enviaré solo texto.",
|
|
49
50
|
"bot.photo_download_error": "🔴 No se pudo descargar la foto",
|
|
50
51
|
"bot.photo_no_caption": "💡 Consejo: agrega un pie de foto para describir que quieres hacer con esta foto.",
|
|
52
|
+
"bot.file_downloading": "⏳ Descargando archivo...",
|
|
53
|
+
"bot.file_too_large": "⚠️ El archivo es demasiado grande (max {maxSizeMb}MB)",
|
|
54
|
+
"bot.file_download_error": "🔴 No se pudo descargar el archivo",
|
|
55
|
+
"bot.model_no_pdf": "⚠️ El modelo actual no admite entrada PDF. Enviaré solo texto.",
|
|
56
|
+
"bot.text_file_too_large": "⚠️ El archivo de texto es demasiado grande (max {maxSizeKb}KB)",
|
|
51
57
|
"status.header_running": "🟢 **OpenCode Server está en ejecución**",
|
|
52
58
|
"status.health.healthy": "Saludable",
|
|
53
59
|
"status.health.unhealthy": "No saludable",
|
|
@@ -70,7 +76,11 @@ export const es = {
|
|
|
70
76
|
"projects.empty": "📭 No se encontraron proyectos.\n\nAbre un directorio en OpenCode y crea al menos una sesión; entonces aparecerá aquí.",
|
|
71
77
|
"projects.select": "Selecciona un proyecto:",
|
|
72
78
|
"projects.select_with_current": "Selecciona un proyecto:\n\nActual: 🏗 {project}",
|
|
79
|
+
"projects.page_indicator": "Página {current}/{total}",
|
|
80
|
+
"projects.prev_page": "⬅️ Anterior",
|
|
81
|
+
"projects.next_page": "Siguiente ➡️",
|
|
73
82
|
"projects.fetch_error": "🔴 OpenCode Server no está disponible u ocurrió un error al cargar los proyectos.",
|
|
83
|
+
"projects.page_load_error": "No se puede cargar esta página. Inténtalo de nuevo.",
|
|
74
84
|
"projects.selected": "✅ Proyecto seleccionado: {project}\n\n📋 La sesión se reinició. Usa /sessions o /new para este proyecto.",
|
|
75
85
|
"projects.select_error": "🔴 No se pudo seleccionar el proyecto.",
|
|
76
86
|
"sessions.project_not_selected": "🏗 No hay un proyecto seleccionado.\n\nPrimero selecciona un proyecto con /projects.",
|
|
@@ -120,6 +130,8 @@ export const es = {
|
|
|
120
130
|
"agent.change_error_callback": "No se pudo cambiar el modo",
|
|
121
131
|
"agent.menu.current": "Modo actual: {name}\n\nSelecciona el modo:",
|
|
122
132
|
"agent.menu.select": "Selecciona el modo de trabajo:",
|
|
133
|
+
"agent.menu.empty": "⚠️ No hay agentes disponibles",
|
|
134
|
+
"agent.menu.error": "🔴 No se pudo obtener la lista de agentes",
|
|
123
135
|
"model.changed_callback": "Modelo cambiado: {name}",
|
|
124
136
|
"model.changed_message": "✅ Modelo cambiado a: {name}",
|
|
125
137
|
"model.change_error_callback": "No se pudo cambiar el modelo",
|
|
@@ -232,6 +244,19 @@ export const es = {
|
|
|
232
244
|
"rename.blocked.expected_name": "⚠️ Introduce el nuevo nombre de la sesión como texto o toca Cancelar en el mensaje de cambio de nombre.",
|
|
233
245
|
"rename.blocked.command_not_allowed": "⚠️ Este comando no está disponible mientras el cambio de nombre espera un nuevo nombre.",
|
|
234
246
|
"rename.button.cancel": "❌ Cancelar",
|
|
247
|
+
"commands.select": "Elige un comando de OpenCode:",
|
|
248
|
+
"commands.empty": "📭 No hay comandos de OpenCode disponibles para este proyecto.",
|
|
249
|
+
"commands.fetch_error": "🔴 No se pudieron cargar los comandos de OpenCode.",
|
|
250
|
+
"commands.no_description": "Sin descripción",
|
|
251
|
+
"commands.button.execute": "✅ Ejecutar",
|
|
252
|
+
"commands.button.cancel": "❌ Cancelar",
|
|
253
|
+
"commands.confirm": "Confirma la ejecución del comando {command}. Para ejecutarlo con argumentos, envía los argumentos como mensaje.",
|
|
254
|
+
"commands.inactive_callback": "Este menú de comandos está inactivo",
|
|
255
|
+
"commands.cancelled_callback": "Cancelado",
|
|
256
|
+
"commands.execute_callback": "Ejecutando comando...",
|
|
257
|
+
"commands.executing_prefix": "⚡ Ejecutando comando:",
|
|
258
|
+
"commands.arguments_empty": "⚠️ Los argumentos no pueden estar vacíos. Envía texto o toca Ejecutar.",
|
|
259
|
+
"commands.execute_error": "🔴 No se pudo ejecutar el comando de OpenCode.",
|
|
235
260
|
"cmd.description.rename": "Renombrar la sesión actual",
|
|
236
261
|
"cli.usage": "Uso:\n opencode-telegram [start] [--mode sources|installed]\n opencode-telegram status\n opencode-telegram stop\n opencode-telegram config\n\nNotas:\n - Sin comando, el valor por defecto es `start`\n - `--mode` actualmente solo se admite para `start`",
|
|
237
262
|
"cli.placeholder.status": "El comando `status` es actualmente un marcador de posición. Las comprobaciones reales de estado se agregarán en la capa de servicio (Fase 5).",
|
package/dist/i18n/ru.js
CHANGED
|
@@ -4,6 +4,7 @@ export const ru = {
|
|
|
4
4
|
"cmd.description.stop": "Прервать текущее действие",
|
|
5
5
|
"cmd.description.sessions": "Список сессий",
|
|
6
6
|
"cmd.description.projects": "Список проектов",
|
|
7
|
+
"cmd.description.commands": "Пользовательские команды",
|
|
7
8
|
"cmd.description.opencode_start": "Запустить OpenCode сервер",
|
|
8
9
|
"cmd.description.opencode_stop": "Остановить OpenCode сервер",
|
|
9
10
|
"cmd.description.help": "Справка",
|
|
@@ -48,6 +49,11 @@ export const ru = {
|
|
|
48
49
|
"bot.photo_model_no_image": "⚠️ Текущая модель не поддерживает изображения. Отправляю только текст.",
|
|
49
50
|
"bot.photo_download_error": "🔴 Не удалось скачать фото",
|
|
50
51
|
"bot.photo_no_caption": "💡 Совет: Добавьте подпись, чтобы описать, что делать с этим фото.",
|
|
52
|
+
"bot.file_downloading": "⏳ Скачиваю файл...",
|
|
53
|
+
"bot.file_too_large": "⚠️ Файл слишком большой (макс. {maxSizeMb}МБ)",
|
|
54
|
+
"bot.file_download_error": "🔴 Не удалось скачать файл",
|
|
55
|
+
"bot.model_no_pdf": "⚠️ Текущая модель не поддерживает PDF. Отправляю только текст.",
|
|
56
|
+
"bot.text_file_too_large": "⚠️ Текстовый файл слишком большой (макс. {maxSizeKb}КБ)",
|
|
51
57
|
"status.header_running": "🟢 **OpenCode Server запущен**",
|
|
52
58
|
"status.health.healthy": "Healthy",
|
|
53
59
|
"status.health.unhealthy": "Unhealthy",
|
|
@@ -70,7 +76,11 @@ export const ru = {
|
|
|
70
76
|
"projects.empty": "📭 Проектов нет.\n\nОткройте директорию в OpenCode и создайте хотя бы одну сессию, после этого она появится здесь.",
|
|
71
77
|
"projects.select": "Выберите проект:",
|
|
72
78
|
"projects.select_with_current": "Выберите проект:\n\nТекущий: 🏗 {project}",
|
|
79
|
+
"projects.page_indicator": "Страница {current}/{total}",
|
|
80
|
+
"projects.prev_page": "⬅️ Назад",
|
|
81
|
+
"projects.next_page": "Вперёд ➡️",
|
|
73
82
|
"projects.fetch_error": "🔴 OpenCode Server недоступен или произошла ошибка при получении списка проектов.",
|
|
83
|
+
"projects.page_load_error": "Не удалось загрузить эту страницу. Попробуйте снова.",
|
|
74
84
|
"projects.selected": "✅ Проект выбран: {project}\n\n📋 Сессия сброшена. Используйте /sessions или /new для работы с этим проектом.",
|
|
75
85
|
"projects.select_error": "🔴 Ошибка при выборе проекта.",
|
|
76
86
|
"sessions.project_not_selected": "🏗 Проект не выбран.\n\nСначала выберите проект командой /projects.",
|
|
@@ -120,6 +130,8 @@ export const ru = {
|
|
|
120
130
|
"agent.change_error_callback": "Ошибка при смене режима",
|
|
121
131
|
"agent.menu.current": "Текущий режим: {name}\n\nВыберите режим:",
|
|
122
132
|
"agent.menu.select": "Выберите режим работы:",
|
|
133
|
+
"agent.menu.empty": "⚠️ Нет доступных агентов",
|
|
134
|
+
"agent.menu.error": "🔴 Не удалось получить список агентов",
|
|
123
135
|
"model.changed_callback": "Модель изменена: {name}",
|
|
124
136
|
"model.changed_message": "✅ Модель изменена на: {name}",
|
|
125
137
|
"model.change_error_callback": "Ошибка при смене модели",
|
|
@@ -232,6 +244,19 @@ export const ru = {
|
|
|
232
244
|
"rename.blocked.expected_name": "⚠️ Введите новое название текстом или нажмите Отмена в сообщении переименования.",
|
|
233
245
|
"rename.blocked.command_not_allowed": "⚠️ Эта команда недоступна, пока ожидается новое название сессии.",
|
|
234
246
|
"rename.button.cancel": "❌ Отмена",
|
|
247
|
+
"commands.select": "Выберите команду OpenCode:",
|
|
248
|
+
"commands.empty": "📭 Для этого проекта нет доступных команд OpenCode.",
|
|
249
|
+
"commands.fetch_error": "🔴 Не удалось загрузить список команд OpenCode.",
|
|
250
|
+
"commands.no_description": "Без описания",
|
|
251
|
+
"commands.button.execute": "✅ Выполнить",
|
|
252
|
+
"commands.button.cancel": "❌ Отмена",
|
|
253
|
+
"commands.confirm": "Подтвердите выполнение команды {command}. Для выполнения с аргументами отправьте аргументы отдельным сообщением.",
|
|
254
|
+
"commands.inactive_callback": "Это меню команд уже неактивно",
|
|
255
|
+
"commands.cancelled_callback": "Отменено",
|
|
256
|
+
"commands.execute_callback": "Запускаю команду...",
|
|
257
|
+
"commands.executing_prefix": "⚡ Выполнение команды:",
|
|
258
|
+
"commands.arguments_empty": "⚠️ Аргументы не могут быть пустыми. Отправьте текст или нажмите Выполнить.",
|
|
259
|
+
"commands.execute_error": "🔴 Не удалось выполнить команду OpenCode.",
|
|
235
260
|
"cmd.description.rename": "Переименовать текущую сессию",
|
|
236
261
|
"cli.usage": "Использование:\n opencode-telegram [start] [--mode sources|installed]\n opencode-telegram status\n opencode-telegram stop\n opencode-telegram config\n\nЗаметки:\n - Без команды по умолчанию используется `start`\n - `--mode` сейчас поддерживается только для `start`",
|
|
237
262
|
"cli.placeholder.status": "Команда `status` пока работает как заглушка. Реальная проверка статуса появится на этапе service-слоя (Этап 5).",
|
package/dist/i18n/zh.js
CHANGED
|
@@ -4,6 +4,7 @@ export const zh = {
|
|
|
4
4
|
"cmd.description.stop": "停止当前操作",
|
|
5
5
|
"cmd.description.sessions": "列出会话",
|
|
6
6
|
"cmd.description.projects": "列出项目",
|
|
7
|
+
"cmd.description.commands": "自定义命令",
|
|
7
8
|
"cmd.description.opencode_start": "启动 OpenCode 服务器",
|
|
8
9
|
"cmd.description.opencode_stop": "停止 OpenCode 服务器",
|
|
9
10
|
"cmd.description.help": "帮助",
|
|
@@ -48,6 +49,11 @@ export const zh = {
|
|
|
48
49
|
"bot.photo_model_no_image": "⚠️ 当前模型不支持图像输入。将仅发送文本。",
|
|
49
50
|
"bot.photo_download_error": "🔴 下载照片失败",
|
|
50
51
|
"bot.photo_no_caption": "💡 提示:添加说明文字以描述你希望对这张照片做什么。",
|
|
52
|
+
"bot.file_downloading": "⏳ 正在下载文件...",
|
|
53
|
+
"bot.file_too_large": "⚠️ 文件过大(最大 {maxSizeMb}MB)",
|
|
54
|
+
"bot.file_download_error": "🔴 下载文件失败",
|
|
55
|
+
"bot.model_no_pdf": "⚠️ 当前模型不支持PDF输入。将仅发送文本。",
|
|
56
|
+
"bot.text_file_too_large": "⚠️ 文本文件过大(最大 {maxSizeKb}KB)",
|
|
51
57
|
"status.header_running": "🟢 **OpenCode 服务器正在运行**",
|
|
52
58
|
"status.health.healthy": "健康",
|
|
53
59
|
"status.health.unhealthy": "不健康",
|
|
@@ -70,7 +76,11 @@ export const zh = {
|
|
|
70
76
|
"projects.empty": "📭 未找到项目。\n\n在 OpenCode 中打开一个目录并至少创建一个会话,然后它会出现在这里。",
|
|
71
77
|
"projects.select": "请选择一个项目:",
|
|
72
78
|
"projects.select_with_current": "请选择一个项目:\n\n当前:🏗 {project}",
|
|
79
|
+
"projects.page_indicator": "第 {current}/{total} 页",
|
|
80
|
+
"projects.prev_page": "⬅️ 上一页",
|
|
81
|
+
"projects.next_page": "下一页 ➡️",
|
|
73
82
|
"projects.fetch_error": "🔴 OpenCode 服务器不可用,或加载项目时发生错误。",
|
|
83
|
+
"projects.page_load_error": "无法加载此页面。请重试。",
|
|
74
84
|
"projects.selected": "✅ 已选择项目:{project}\n\n📋 会话已重置。请在此项目中使用 /sessions 或 /new。",
|
|
75
85
|
"projects.select_error": "🔴 选择项目失败。",
|
|
76
86
|
"sessions.project_not_selected": "🏗 未选择项目。\n\n请先使用 /projects 选择一个项目。",
|
|
@@ -120,6 +130,8 @@ export const zh = {
|
|
|
120
130
|
"agent.change_error_callback": "切换模式失败",
|
|
121
131
|
"agent.menu.current": "当前模式:{name}\n\n请选择模式:",
|
|
122
132
|
"agent.menu.select": "请选择工作模式:",
|
|
133
|
+
"agent.menu.empty": "⚠️ 没有可用的代理",
|
|
134
|
+
"agent.menu.error": "🔴 获取代理列表失败",
|
|
123
135
|
"model.changed_callback": "模型已更改:{name}",
|
|
124
136
|
"model.changed_message": "✅ 模型已切换为:{name}",
|
|
125
137
|
"model.change_error_callback": "切换模型失败",
|
|
@@ -232,6 +244,19 @@ export const zh = {
|
|
|
232
244
|
"rename.blocked.expected_name": "⚠️ 请以文本输入新会话名称,或在重命名消息中点击取消。",
|
|
233
245
|
"rename.blocked.command_not_allowed": "⚠️ 重命名等待新名称期间不可用此命令。",
|
|
234
246
|
"rename.button.cancel": "❌ 取消",
|
|
247
|
+
"commands.select": "请选择一个 OpenCode 命令:",
|
|
248
|
+
"commands.empty": "📭 当前项目没有可用的 OpenCode 命令。",
|
|
249
|
+
"commands.fetch_error": "🔴 加载 OpenCode 命令失败。",
|
|
250
|
+
"commands.no_description": "无描述",
|
|
251
|
+
"commands.button.execute": "✅ 执行",
|
|
252
|
+
"commands.button.cancel": "❌ 取消",
|
|
253
|
+
"commands.confirm": "请确认执行命令 {command}。若需带参数执行,请发送一条包含参数的消息。",
|
|
254
|
+
"commands.inactive_callback": "该命令菜单已失效",
|
|
255
|
+
"commands.cancelled_callback": "已取消",
|
|
256
|
+
"commands.execute_callback": "正在执行命令...",
|
|
257
|
+
"commands.executing_prefix": "⚡ 执行命令:",
|
|
258
|
+
"commands.arguments_empty": "⚠️ 参数不能为空。请发送文本或点击执行。",
|
|
259
|
+
"commands.execute_error": "🔴 执行 OpenCode 命令失败。",
|
|
235
260
|
"cmd.description.rename": "重命名当前会话",
|
|
236
261
|
"cli.usage": "用法:\n opencode-telegram [start] [--mode sources|installed]\n opencode-telegram status\n opencode-telegram stop\n opencode-telegram config\n\n说明:\n - 不带命令时默认执行 `start`\n - `--mode` 目前仅支持 `start` 命令",
|
|
237
262
|
"cli.placeholder.status": "命令 `status` 目前是占位符。真实状态检查将会在 service 层(阶段 5)添加。",
|
package/dist/model/types.js
CHANGED
|
@@ -8,12 +8,10 @@
|
|
|
8
8
|
* @returns Formatted string "providerID/modelID"
|
|
9
9
|
*/
|
|
10
10
|
export function formatModelForButton(providerID, modelID) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
return `🤖 ${formatted}`;
|
|
11
|
+
// If model name is too long, we only truncate the model part
|
|
12
|
+
const displayModelId = modelID.length > 20 ? `${modelID.substring(0, 17)}...` : modelID;
|
|
13
|
+
const displayProviderId = providerID.length > 15 ? `${providerID.substring(0, 12)}...` : providerID;
|
|
14
|
+
return `🤖 ${displayProviderId}\n${displayModelId}`;
|
|
17
15
|
}
|
|
18
16
|
/**
|
|
19
17
|
* Format model for display in messages (full format)
|