polygram 0.5.1 → 0.5.2
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/.claude-plugin/plugin.json +1 -1
- package/package.json +1 -1
- package/polygram.js +54 -13
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
|
|
3
3
|
"name": "polygram",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.2",
|
|
5
5
|
"description": "Telegram integration for Claude Code that preserves the OpenClaw per-chat session model. Migration target for OpenClaw users. Multi-bot, multi-chat, per-topic isolation; SQLite transcripts; inline-keyboard approvals. Bundles /polygram:status|logs|pair-code|approvals admin commands and a history skill.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"telegram",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "polygram",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "Telegram daemon for Claude Code that preserves the OpenClaw per-chat session model. Migration path for OpenClaw users moving to Claude Code.",
|
|
5
5
|
"main": "lib/ipc-client.js",
|
|
6
6
|
"bin": {
|
package/polygram.js
CHANGED
|
@@ -760,6 +760,39 @@ function buildConfigKeyboard(chatConfig, show = 'all') {
|
|
|
760
760
|
return { inline_keyboard: rows };
|
|
761
761
|
}
|
|
762
762
|
|
|
763
|
+
// Card text shown above the inline keyboard. Includes plain-language
|
|
764
|
+
// guidance on when to pick which model / effort, since most users
|
|
765
|
+
// (especially in shared groups) don't know which option to tap.
|
|
766
|
+
const MODEL_VERSIONS_DESC = { opus: 'claude-opus-4-6', sonnet: 'claude-sonnet-4-6', haiku: 'claude-haiku-4-5' };
|
|
767
|
+
|
|
768
|
+
function formatConfigInfoText(chatConfig, show, sessionKey) {
|
|
769
|
+
const alive = pm.has(sessionKey) && !pm.get(sessionKey).closed;
|
|
770
|
+
const ver = MODEL_VERSIONS_DESC[chatConfig.model] || chatConfig.model;
|
|
771
|
+
const head = `Model: ${chatConfig.model} (${ver})\nEffort: ${chatConfig.effort}\nAgent: ${chatConfig.agent}\nProcess: ${alive ? 'warm' : 'cold'}\nSession: ${getClaudeSessionId(db, sessionKey)?.slice(0, 8) || 'new'}`;
|
|
772
|
+
|
|
773
|
+
const modelHelp = [
|
|
774
|
+
'',
|
|
775
|
+
'**Models**',
|
|
776
|
+
'🧠 **opus** — глубокий анализ, code refactor, сверка из 3+ источников. ~5× стоимость sonnet.',
|
|
777
|
+
'🤖 **sonnet** — дефолт. Большинство ops, code review, document summary.',
|
|
778
|
+
'⚡ **haiku** — простые быстрые задачи, классификация, lookup.',
|
|
779
|
+
].join('\n');
|
|
780
|
+
|
|
781
|
+
const effortHelp = [
|
|
782
|
+
'',
|
|
783
|
+
'**Effort** — потолок «сколько Claude может думать». На простых вопросах он сам отвечает быстро, на сложных тратит больше токенов. Можно безопасно ставить выше — он не разгонится без нужды.',
|
|
784
|
+
'• **low** — fast replies, минимум reasoning. Casual chat, simple lookups.',
|
|
785
|
+
'• **medium** — balanced default. Подходит почти всем.',
|
|
786
|
+
'• **high** — сложные многошаговые задачи. Audit, debug, multi-source.',
|
|
787
|
+
'• **xhigh** / **max** — самые тяжёлые. Hard reasoning, edge cases.',
|
|
788
|
+
].join('\n');
|
|
789
|
+
|
|
790
|
+
let body = head;
|
|
791
|
+
if (show === 'model' || show === 'all') body += '\n' + modelHelp;
|
|
792
|
+
if (show === 'effort' || show === 'all') body += '\n' + effortHelp;
|
|
793
|
+
return body;
|
|
794
|
+
}
|
|
795
|
+
|
|
763
796
|
function approvalCardText(row, opts = {}) {
|
|
764
797
|
// No parse_mode is used on this card — tool_name/turn_id/tool_input
|
|
765
798
|
// originate from the Claude subprocess and could contain Markdown special
|
|
@@ -1005,17 +1038,29 @@ async function handleConfigCallback(ctx) {
|
|
|
1005
1038
|
}
|
|
1006
1039
|
}
|
|
1007
1040
|
|
|
1008
|
-
// Re-render the card with updated
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
// Detect original card type from existing reply_markup row count.
|
|
1041
|
+
// Re-render the card with updated ✓ + the same help text shown initially.
|
|
1042
|
+
// Detect original card type (model-only / effort-only / both) by counting
|
|
1043
|
+
// rows in the existing reply_markup so the user sees the same layout
|
|
1044
|
+
// they tapped into.
|
|
1013
1045
|
const existingRows = ctx.callbackQuery.message?.reply_markup?.inline_keyboard?.length || 0;
|
|
1014
|
-
const
|
|
1046
|
+
const showRow = existingRows >= 2 ? 'all' : setting;
|
|
1047
|
+
// chatId works as a session-key proxy here for the warm-process check
|
|
1048
|
+
// (isolateTopics chats might have multiple keys but for this card we
|
|
1049
|
+
// just want a representative state).
|
|
1050
|
+
const newInfo = formatConfigInfoText(chatConfig, showRow, chatId);
|
|
1051
|
+
const newKeyboard = buildConfigKeyboard(chatConfig, showRow);
|
|
1015
1052
|
try {
|
|
1016
|
-
|
|
1053
|
+
// Pre-format the markdown→HTML ourselves so editMessageText can be
|
|
1054
|
+
// called with the right parse_mode (the bot.api.editMessageText path
|
|
1055
|
+
// bypasses tg() / applyFormatting in the chat-action approval card,
|
|
1056
|
+
// but here we DO want HTML).
|
|
1057
|
+
const { toTelegramHtml } = require('./lib/telegram-format');
|
|
1058
|
+
const { text: html, parseMode } = toTelegramHtml(newInfo);
|
|
1059
|
+
await ctx.editMessageText(html, {
|
|
1060
|
+
reply_markup: newKeyboard,
|
|
1061
|
+
...(parseMode && { parse_mode: parseMode }),
|
|
1062
|
+
});
|
|
1017
1063
|
} catch (err) {
|
|
1018
|
-
// Edit may fail if message is too old or unchanged — not fatal.
|
|
1019
1064
|
console.error(`[${BOT_NAME}] config-card edit failed: ${err.message}`);
|
|
1020
1065
|
}
|
|
1021
1066
|
|
|
@@ -1114,12 +1159,8 @@ async function handleMessage(sessionKey, chatId, msg, bot) {
|
|
|
1114
1159
|
};
|
|
1115
1160
|
|
|
1116
1161
|
if (botAllowsCommands && (text === '/model' || text === '/config' || text === '/effort')) {
|
|
1117
|
-
const alive = pm.has(sessionKey) && !pm.get(sessionKey).closed;
|
|
1118
|
-
const ver = MODEL_VERSIONS[chatConfig.model] || chatConfig.model;
|
|
1119
|
-
const info = `Model: ${chatConfig.model} (${ver})\nEffort: ${chatConfig.effort}\nAgent: ${chatConfig.agent}\nProcess: ${alive ? 'warm' : 'cold'}\nSession: ${getClaudeSessionId(db, sessionKey)?.slice(0, 8) || 'new'}`;
|
|
1120
|
-
// Inline keyboard so users tap to switch instead of typing exact
|
|
1121
|
-
// names (avoids "sonet" typo problem).
|
|
1122
1162
|
const show = text === '/effort' ? 'effort' : text === '/model' ? 'model' : 'all';
|
|
1163
|
+
const info = formatConfigInfoText(chatConfig, show, sessionKey);
|
|
1123
1164
|
const reply_markup = buildConfigKeyboard(chatConfig, show);
|
|
1124
1165
|
await sendReply(info, { params: { reply_markup } });
|
|
1125
1166
|
return;
|