@hmawla/co-assistant 1.0.7 → 1.0.9

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 CHANGED
@@ -1,5 +1,7 @@
1
1
  # 🤖 Co-Assistant
2
2
 
3
+ **[Homepage](https://hmawla.github.io/co-assistant)** · **[npm](https://www.npmjs.com/package/@hmawla/co-assistant)** · **[Plugin Guide](docs/plugin-development.md)** · **[CLI Reference](docs/cli-reference.md)**
4
+
3
5
  AI-powered Telegram personal assistant built on the GitHub Copilot SDK.
4
6
 
5
7
  Chat with state-of-the-art AI models (GPT-5, Claude Sonnet 4, o3, and more) directly from Telegram. Extend it with plugins for Gmail, Google Calendar, or build your own.
@@ -385,7 +387,7 @@ Both files are injected as system-level context on every message:
385
387
 
386
388
  | Plugin | Tools provided |
387
389
  |--------|---------------|
388
- | **Gmail** | Search emails, read email, send email, send reply |
390
+ | **Gmail** | Search threads, search emails, read email, send email, get thread |
389
391
  | **Google Calendar** | List events, create event, update event, delete event |
390
392
 
391
393
  ### Install Plugins
package/dist/cli/index.js CHANGED
@@ -976,6 +976,7 @@ var init_plugin_health = __esm({
976
976
  var message_exports = {};
977
977
  __export(message_exports, {
978
978
  createMessageHandler: () => createMessageHandler,
979
+ safeSendMarkdown: () => safeSendMarkdown,
979
980
  splitMessage: () => splitMessage
980
981
  });
981
982
  function splitMessage(text, maxLength = 4096) {
@@ -1001,6 +1002,19 @@ function splitMessage(text, maxLength = 4096) {
1001
1002
  }
1002
1003
  return chunks.filter((c) => c.length > 0);
1003
1004
  }
1005
+ async function safeSendMarkdown(sendFn, text, extra = {}) {
1006
+ try {
1007
+ await sendFn(text, { parse_mode: "Markdown", ...extra });
1008
+ } catch (err) {
1009
+ const msg = err instanceof Error ? err.message : String(err);
1010
+ if (msg.includes("can't parse entities")) {
1011
+ const plain = text.replace(/[*_`]/g, "");
1012
+ await sendFn(plain, extra);
1013
+ } else {
1014
+ throw err;
1015
+ }
1016
+ }
1017
+ }
1004
1018
  function createMessageHandler(deps) {
1005
1019
  const { sessionManager: sessionManager2, conversationRepo } = deps;
1006
1020
  return async (ctx, text) => {
@@ -3209,7 +3223,11 @@ ${state.processedIds.map((id) => `- ${id}`).join("\n")}` : "No previously proces
3209
3223
  `;
3210
3224
  const chunks = splitMessage(header + clean);
3211
3225
  for (const chunk of chunks) {
3212
- await ctx.reply(chunk, { parse_mode: "Markdown", ...replyOpts });
3226
+ await safeSendMarkdown(
3227
+ (text, extra) => ctx.reply(text, extra),
3228
+ chunk,
3229
+ replyOpts
3230
+ );
3213
3231
  }
3214
3232
  }
3215
3233
  } catch (err) {
@@ -3300,7 +3318,10 @@ ${state.processedIds.map((id) => `- ${id}`).join("\n")}` : "No previously proces
3300
3318
  const fullMessage = header + response;
3301
3319
  const chunks = splitMessage(fullMessage);
3302
3320
  for (const chunk of chunks) {
3303
- await bot.getBot().telegram.sendMessage(chatId, chunk, { parse_mode: "Markdown" });
3321
+ await safeSendMarkdown(
3322
+ (text, extra) => bot.getBot().telegram.sendMessage(chatId, text, extra),
3323
+ chunk
3324
+ );
3304
3325
  }
3305
3326
  } catch (err) {
3306
3327
  this.logger.error({ err, eventName }, "Failed to send heartbeat response via Telegram");
@@ -4581,7 +4602,7 @@ function registerHeartbeatCommand(program2) {
4581
4602
  const { getConfig: getConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
4582
4603
  const { copilotClient: copilotClient2 } = await Promise.resolve().then(() => (init_client(), client_exports));
4583
4604
  const { sessionManager: sessionManager2 } = await Promise.resolve().then(() => (init_session(), session_exports));
4584
- const { splitMessage: splitMessage2 } = await Promise.resolve().then(() => (init_message(), message_exports));
4605
+ const { splitMessage: splitMessage2, safeSendMarkdown: safeSendMarkdown2 } = await Promise.resolve().then(() => (init_message(), message_exports));
4585
4606
  let config;
4586
4607
  try {
4587
4608
  config = getConfig2();
@@ -4672,7 +4693,10 @@ ${state.processedIds.map((id) => `- ${id}`).join("\n")}` : "No previously proces
4672
4693
  `;
4673
4694
  const chunks = splitMessage2(header + cleanResponse);
4674
4695
  for (const chunk of chunks) {
4675
- await telegram.sendMessage(chatId, chunk, { parse_mode: "Markdown" });
4696
+ await safeSendMarkdown2(
4697
+ (text, extra) => telegram.sendMessage(chatId, text, extra),
4698
+ chunk
4699
+ );
4676
4700
  }
4677
4701
  console.log(" \u2713 Sent to Telegram");
4678
4702
  } catch (err) {