@inetafrica/open-claudia 2.2.10 → 2.2.11

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/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## v2.2.11
4
+ - Telegram replies now get channel-specific formatting guidance in the system prompt: short mobile-friendly sections, single-asterisk Telegram Markdown labels, no tables/headings/Markdown links, and no noisy quotes/backticks around normal business terms.
5
+ - Telegram final/progress messages now request Markdown parse mode, and edited messages support the same parse mode with a plain-text fallback if Telegram rejects the markup.
6
+
3
7
  ## v2.2.10
4
8
  - System prompt: explicitly tell the model not to use the Claude Code harness's built-in `ScheduleWakeup` / `CronCreate` tools. Those register timers inside the per-turn Claude Code subprocess, which exits at end-of-turn, so the wakeup silently never fires. Only the `open-claudia schedule-wakeup` / `cron-add` CLI commands (owned by the long-running bot) actually survive. Mirrors the existing warning we already had for harness `TaskCreate` / `TaskUpdate` vs `open-claudia task`.
5
9
 
@@ -239,15 +239,21 @@ class TelegramAdapter {
239
239
  }
240
240
 
241
241
  async edit(channelId, messageId, text, opts = {}) {
242
+ const o = { chat_id: channelId, message_id: messageId };
243
+ if (opts.parseMode) o.parse_mode = opts.parseMode;
244
+ const kb = this._normalizeKeyboard(opts.keyboard);
245
+ if (kb) o.reply_markup = kb;
246
+
242
247
  try {
243
- const o = { chat_id: channelId, message_id: messageId };
244
- const kb = this._normalizeKeyboard(opts.keyboard);
245
- if (kb) o.reply_markup = kb;
246
248
  await this.bot.editMessageText(text, o);
247
249
  } catch (e) {
248
250
  const errMsg = e.message || "";
249
251
  if (errMsg.includes("retry after")) return;
250
252
  if (errMsg.includes("message is not modified")) return;
253
+ if (opts.parseMode && o.parse_mode) {
254
+ delete o.parse_mode;
255
+ try { await this.bot.editMessageText(text, o); return; } catch (e2) {}
256
+ }
251
257
  if (!errMsg.includes("message to edit not found")) console.error("Edit error:", errMsg);
252
258
  }
253
259
  }
package/core/runner.js CHANGED
@@ -22,6 +22,11 @@ const {
22
22
  const { getClaudeOAuthToken, claudeAuthRecoveryMessage, isClaudeAuthErrorText, claudeUsageLimitMessage, isClaudeUsageLimitText, runClaudeAuthStatusDiagnostic, claudeSubprocessEnv } = require("./auth-flow");
23
23
  const loopback = require("./loopback");
24
24
 
25
+ function telegramMarkdownOpts(extra = {}) {
26
+ const adapter = currentAdapter();
27
+ return adapter?.type === "telegram" ? { ...extra, parseMode: "Markdown" } : extra;
28
+ }
29
+
25
30
  function chatEnvOverlay() {
26
31
  const adapter = currentAdapter();
27
32
  const channelId = currentChannelId();
@@ -462,9 +467,9 @@ async function runClaude(prompt, cwd, replyToMsgId, opts = {}) {
462
467
  const display = formatProgress(assistantText, toolUses, currentTool, elapsed, currentToolDetail);
463
468
  if (display && display !== lastUpdate) {
464
469
  if (!state.statusMessageId && assistantText) {
465
- state.statusMessageId = await send(display.length > 4000 ? display.slice(-4000) : display, { replyTo: replyToMsgId });
470
+ state.statusMessageId = await send(display.length > 4000 ? display.slice(-4000) : display, telegramMarkdownOpts({ replyTo: replyToMsgId }));
466
471
  } else if (state.statusMessageId) {
467
- await editMessage(state.statusMessageId, display.length > 4000 ? display.slice(-4000) : display);
472
+ await editMessage(state.statusMessageId, display.length > 4000 ? display.slice(-4000) : display, telegramMarkdownOpts());
468
473
  }
469
474
  lastUpdate = display;
470
475
  }
@@ -651,12 +656,12 @@ async function runClaude(prompt, cwd, replyToMsgId, opts = {}) {
651
656
  const firstChunk = chunks[0];
652
657
 
653
658
  if (state.statusMessageId && chunks.length === 1) {
654
- await editMessage(state.statusMessageId, firstChunk);
659
+ await editMessage(state.statusMessageId, firstChunk, telegramMarkdownOpts());
655
660
  } else {
656
- const sent = await send(firstChunk, { replyTo: replyToMsgId });
661
+ const sent = await send(firstChunk, telegramMarkdownOpts({ replyTo: replyToMsgId }));
657
662
  if (!sent) await send(firstChunk);
658
663
  for (let i = 1; i < chunks.length; i++) {
659
- await send(chunks[i]);
664
+ await send(chunks[i], telegramMarkdownOpts());
660
665
  }
661
666
  }
662
667
  if (code !== 0 && code !== null) await send(`Exit code: ${code}`);
@@ -73,6 +73,41 @@ function buildSystemPrompt() {
73
73
  }
74
74
  } catch (e) {}
75
75
 
76
+ const channelFormattingBlock = adapter?.type === "telegram"
77
+ ? `
78
+ ## Telegram formatting
79
+ Telegram is mobile-first and narrow. Optimize for readability in a small chat bubble.
80
+
81
+ Use Telegram Markdown v1 only:
82
+ - Bold labels with single asterisks: *Status:* / *Done:* / *Blocked:* / *Next:*
83
+ - Italic with single underscores only when genuinely useful.
84
+ - Inline code with backticks only for commands, file paths, IDs, short field names, and exact errors.
85
+ - Fenced code blocks only for short commands or snippets. Do not paste long logs; save/send a file instead.
86
+
87
+ Avoid formatting that renders badly or noisily in Telegram:
88
+ - No Markdown tables.
89
+ - No Markdown headings like #, ##, ###.
90
+ - No CommonMark bold like **bold**; use *bold*.
91
+ - No Markdown links like [text](url); use plain URLs when needed.
92
+ - Do not wrap ordinary business words in backticks or quote marks. For example, write Payments completed, not \`Payments\` completed or 'Payments' completed.
93
+ - Avoid large paragraphs. Use short sections, blank lines, and 3-7 concise bullets.
94
+
95
+ Good Telegram pattern:
96
+ *Status:* CRM sync is still running cleanly.
97
+
98
+ - Bills and Calls completed.
99
+ - Leads completed with 20 rows.
100
+ - Payments advanced to 2026-05-17 10:50.
101
+
102
+ *Issue:* JSON parse error after Retention. I’m checking that stream next.
103
+ `
104
+ : adapter?.type === "kazee"
105
+ ? `
106
+ ## Kazee Chat formatting
107
+ Keep replies clean and mobile-readable. Use short paragraphs and bullets. Avoid Markdown tables unless the user explicitly asks for a table.
108
+ `
109
+ : "";
110
+
76
111
  return `
77
112
  ${soul}
78
113
 
@@ -92,7 +127,7 @@ ${soul}
92
127
  - Received user files directory: ${FILES_DIR}
93
128
 
94
129
  ${transcriptPointerNote(state)}
95
- ${currentSpeakerBlock}${teamBlock}${pendingTasksBlock}${slashCommandsBlock}
130
+ ${currentSpeakerBlock}${teamBlock}${pendingTasksBlock}${slashCommandsBlock}${channelFormattingBlock}
96
131
  ## Delivery
97
132
  Reply normally in your final answer. To send a file, image, or voice clip back to the current chat, run the bot CLI from inside this task — channel context is already in the env:
98
133
  - \`open-claudia send-file <path> [caption]\` — any document/binary
@@ -151,7 +186,7 @@ If you tell the user "I'll check back in N minutes" or "I'll run this every morn
151
186
 
152
187
  ## Guidelines
153
188
  - Keep responses concise — many users are on mobile.
154
- - Markdown: *bold*, _italic_, \`code\`, \`\`\`code blocks\`\`\` work on both Telegram and Kazee. Skip headers (#) and links [text](url).
189
+ - Markdown: use simple chat-safe formatting only. On Telegram follow the Telegram formatting section exactly; on Kazee use short bullets/paragraphs and avoid tables unless requested.
155
190
  - For long output (logs, diffs, large code), save to a file and send it as an artifact instead of pasting walls of text.
156
191
  - Act on screenshots (fix bugs, implement designs) — don't just describe what you see.
157
192
  - When the user sends a file, it is saved in the received files directory above. Read it with the Read tool.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inetafrica/open-claudia",
3
- "version": "2.2.10",
3
+ "version": "2.2.11",
4
4
  "description": "Your always-on AI coding assistant — Claude Code, Cursor Agent, and OpenAI Codex via Telegram or Kazee Chat",
5
5
  "main": "bot.js",
6
6
  "bin": {