polygram 0.13.0 → 0.13.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.
@@ -46,4 +46,22 @@ function filterConfigToBot(config, botName) {
46
46
  };
47
47
  }
48
48
 
49
- module.exports = { parseBotArg, parseDbArg, filterConfigToBot };
49
+ /**
50
+ * Resolve the active bot's effective config: the per-bot block
51
+ * `config.bots[botName]` layered OVER the shared top-level `bot` block, so
52
+ * shared fields (e.g. `apiRoot`) set once at the top level survive, and any
53
+ * per-bot field of the same name wins.
54
+ *
55
+ * Without this merge, a plain `config.bot = config.bots[botName]` silently
56
+ * DROPS every top-level shared field. That orphaned `apiRoot` and ran both VPS
57
+ * bots on cloud Telegram (20/50) instead of the 2 GB local Bot API server for
58
+ * weeks (discovered 2026-06-16) — createBot reads `config.bot.apiRoot` after
59
+ * the alias, so the top-level value never reached it.
60
+ */
61
+ function activeBotConfig(config, botName) {
62
+ const top = (config && config.bot) || {};
63
+ const perBot = (config && config.bots && config.bots[botName]) || {};
64
+ return { ...top, ...perBot };
65
+ }
66
+
67
+ module.exports = { parseBotArg, parseDbArg, filterConfigToBot, activeBotConfig };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polygram",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
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
@@ -88,7 +88,7 @@ const agentLoader = require('./lib/agents/loader');
88
88
  const { createSender } = require('./lib/telegram/api');
89
89
  const { createAsyncLock } = require('./lib/async-lock');
90
90
  const { sweepInbox } = require('./lib/db/inbox');
91
- const { parseBotArg, parseDbArg, filterConfigToBot } = require('./lib/config-scope');
91
+ const { parseBotArg, parseDbArg, filterConfigToBot, activeBotConfig } = require('./lib/config-scope');
92
92
  const { createStore: createPairingsStore, parseTtl: parsePairingTtl } = require('./lib/db/pairings');
93
93
  const { transcribe: transcribeVoice, isVoiceAttachment } = require('./lib/telegram/voice');
94
94
  const { createStreamer } = require('./lib/telegram/streamer');
@@ -2136,10 +2136,12 @@ async function main() {
2136
2136
  }
2137
2137
  try {
2138
2138
  config = filterConfigToBot(config, BOT_NAME);
2139
- // Convenience: config.bot is the current bot's config block. After the
2140
- // filter, config.bots has exactly one entry; this alias keeps call sites
2141
- // from re-indexing by name.
2142
- config.bot = config.bots[BOT_NAME];
2139
+ // Convenience: config.bot is the current bot's EFFECTIVE config the
2140
+ // per-bot block layered over the shared top-level `bot` block (so shared
2141
+ // fields like apiRoot survive; per-bot fields win). A plain
2142
+ // `= config.bots[BOT_NAME]` silently dropped top-level shared fields and
2143
+ // orphaned apiRoot (both bots ran on cloud, not the 2GB local server).
2144
+ config.bot = activeBotConfig(config, BOT_NAME);
2143
2145
  } catch (err) {
2144
2146
  console.error(`[fatal] ${err.message}`);
2145
2147
  process.exit(2);