polygram 0.5.7 → 0.5.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/lib/process-manager.js +13 -4
- package/package.json +1 -1
- package/polygram.js +22 -4
package/lib/process-manager.js
CHANGED
|
@@ -168,6 +168,12 @@ class ProcessManager {
|
|
|
168
168
|
* If the queue is empty, kill now; otherwise mark the entry so it kills
|
|
169
169
|
* itself when the last pending resolves. Next send() respawns fresh
|
|
170
170
|
* with whatever config spawnFn reads at that moment.
|
|
171
|
+
*
|
|
172
|
+
* onRespawn fires with `wasDrained=true` ONLY when we waited for an
|
|
173
|
+
* in-flight turn to finish before swapping. The immediate-kill case
|
|
174
|
+
* (queue empty at request time) calls onRespawn with `wasDrained=false`
|
|
175
|
+
* so callers can decide whether to post a user-visible confirmation
|
|
176
|
+
* (which is redundant noise when the user wasn't waiting on a turn).
|
|
171
177
|
*/
|
|
172
178
|
requestRespawn(sessionKey, reason = 'config-change') {
|
|
173
179
|
const entry = this.procs.get(sessionKey);
|
|
@@ -181,17 +187,17 @@ class ProcessManager {
|
|
|
181
187
|
});
|
|
182
188
|
if (entry.pendingQueue.length === 0) {
|
|
183
189
|
// Queue empty — kill immediately, fire onRespawn after close.
|
|
184
|
-
this._killAndNotifyRespawn(sessionKey, reason).catch(() => {});
|
|
190
|
+
this._killAndNotifyRespawn(sessionKey, reason, false).catch(() => {});
|
|
185
191
|
return { killed: true, queued: 0 };
|
|
186
192
|
}
|
|
187
193
|
return { killed: false, queued: entry.pendingQueue.length };
|
|
188
194
|
}
|
|
189
195
|
|
|
190
|
-
async _killAndNotifyRespawn(sessionKey, reason) {
|
|
196
|
+
async _killAndNotifyRespawn(sessionKey, reason, wasDrained) {
|
|
191
197
|
const entry = this.procs.get(sessionKey);
|
|
192
198
|
await this.kill(sessionKey);
|
|
193
199
|
if (this.onRespawn && entry) {
|
|
194
|
-
try { this.onRespawn(sessionKey, reason, entry); }
|
|
200
|
+
try { this.onRespawn(sessionKey, reason, entry, wasDrained); }
|
|
195
201
|
catch (err) { this.logger.error(`[pm] onRespawn: ${err.message}`); }
|
|
196
202
|
}
|
|
197
203
|
}
|
|
@@ -321,7 +327,10 @@ class ProcessManager {
|
|
|
321
327
|
chat_id: entry.chatId,
|
|
322
328
|
reason,
|
|
323
329
|
});
|
|
324
|
-
this
|
|
330
|
+
// wasDrained=true: this path runs after the queue emptied
|
|
331
|
+
// naturally (an in-flight turn finished), so the user was
|
|
332
|
+
// waiting and the confirmation message is meaningful.
|
|
333
|
+
this._killAndNotifyRespawn(sessionKey, reason, true).catch(() => {});
|
|
325
334
|
}
|
|
326
335
|
}
|
|
327
336
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "polygram",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.9",
|
|
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
|
@@ -811,7 +811,18 @@ function buildConfigKeyboard(chatConfig, show = 'all') {
|
|
|
811
811
|
// Card text shown above the inline keyboard. Includes plain-language
|
|
812
812
|
// guidance on when to pick which model / effort, since most users
|
|
813
813
|
// (especially in shared groups) don't know which option to tap.
|
|
814
|
-
|
|
814
|
+
//
|
|
815
|
+
// Model versions: polygram passes the alias ("opus", "sonnet", "haiku")
|
|
816
|
+
// to claude, which resolves it to the latest snapshot. We mirror those
|
|
817
|
+
// snapshots here for display only, and verify them on each release with
|
|
818
|
+
// `claude --model <alias>` (probing the system:init event's `model`
|
|
819
|
+
// field). Bumping is a manual step — when claude releases a new
|
|
820
|
+
// snapshot the alias maps to, update this map and ship.
|
|
821
|
+
const MODEL_VERSIONS_DESC = {
|
|
822
|
+
opus: 'claude-opus-4-7',
|
|
823
|
+
sonnet: 'claude-sonnet-4-6',
|
|
824
|
+
haiku: 'claude-haiku-4-5',
|
|
825
|
+
};
|
|
815
826
|
|
|
816
827
|
function formatConfigInfoText(chatConfig, show, sessionKey) {
|
|
817
828
|
const alive = pm.has(sessionKey) && !pm.get(sessionKey).closed;
|
|
@@ -1196,7 +1207,9 @@ async function handleMessage(sessionKey, chatId, msg, bot) {
|
|
|
1196
1207
|
...(tid && { message_thread_id: tid }),
|
|
1197
1208
|
});
|
|
1198
1209
|
|
|
1199
|
-
|
|
1210
|
+
// Single source of truth at module scope (MODEL_VERSIONS_DESC) — see the
|
|
1211
|
+
// comment there for the bump procedure.
|
|
1212
|
+
const MODEL_VERSIONS = MODEL_VERSIONS_DESC;
|
|
1200
1213
|
|
|
1201
1214
|
const botAllowsCommands = !!config.bot?.allowConfigCommands;
|
|
1202
1215
|
const cmdUser = msg.from?.first_name || msg.from?.username || null;
|
|
@@ -2161,8 +2174,13 @@ async function main() {
|
|
|
2161
2174
|
},
|
|
2162
2175
|
// Fires after a graceful /model or /effort drain has actually
|
|
2163
2176
|
// swapped to the new settings. Post a confirmation back to the
|
|
2164
|
-
// chat
|
|
2165
|
-
|
|
2177
|
+
// chat ONLY when wasDrained=true — the user actively waited for an
|
|
2178
|
+
// in-flight turn to finish before the switch took effect, so the
|
|
2179
|
+
// explicit "switched" message is meaningful. When the kill was
|
|
2180
|
+
// immediate (queue empty), the inline-card update + button toast
|
|
2181
|
+
// already convey "done", and a separate message is just noise.
|
|
2182
|
+
onRespawn: (sessionKey, reason, entry, wasDrained) => {
|
|
2183
|
+
if (!wasDrained) return;
|
|
2166
2184
|
const chatId = entry.chatId;
|
|
2167
2185
|
if (!chatId) return;
|
|
2168
2186
|
const chatConfig = config.chats[chatId];
|