polygram 0.8.0-rc.59 → 0.8.0-rc.60
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 +32 -10
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
|
|
3
3
|
"name": "polygram",
|
|
4
|
-
"version": "0.8.0-rc.
|
|
4
|
+
"version": "0.8.0-rc.60",
|
|
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 plus history (transcript queries) and polygram-send (out-of-turn IPC sends with file-upload validation) skills.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"telegram",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "polygram",
|
|
3
|
-
"version": "0.8.0-rc.
|
|
3
|
+
"version": "0.8.0-rc.60",
|
|
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
|
@@ -2085,10 +2085,37 @@ async function handleMessage(sessionKey, chatId, msg, bot) {
|
|
|
2085
2085
|
const cmdUser = msg.from?.first_name || msg.from?.username || null;
|
|
2086
2086
|
const cmdUserId = msg.from?.id || null;
|
|
2087
2087
|
|
|
2088
|
+
// Mark the inbound row terminal so boot replay doesn't pick it up
|
|
2089
|
+
// again. Must fire down EVERY non-throwing exit path (early returns
|
|
2090
|
+
// for error / NO_REPLY, streamed-reply preview-becomes-final, the
|
|
2091
|
+
// discard+redeliver branch, regular reply at end). Earlier versions
|
|
2092
|
+
// only marked at the bottom of try, so streamed-reply early returns
|
|
2093
|
+
// left handler_status stuck at 'dispatched' forever and the next
|
|
2094
|
+
// boot replayed every long turn.
|
|
2095
|
+
//
|
|
2096
|
+
// rc.59: hoisted ABOVE sendReply (was originally below all slash
|
|
2097
|
+
// commands) so sendReply can call it. Slash commands like /compact
|
|
2098
|
+
// /new /reset /model /effort all reply via sendReply but never
|
|
2099
|
+
// dispatched a turn, so they were leaving handler_status='dispatched'
|
|
2100
|
+
// forever. Boot-replay (now with rc.57's auto-derived 72-min window
|
|
2101
|
+
// for chats with maxTurn=3600) would then re-fire the same /compact
|
|
2102
|
+
// command — which post-compaction lands in a stale-session state and
|
|
2103
|
+
// emits "🗜️ No active session — /compact only works once a turn has
|
|
2104
|
+
// started." Visible duplicate-reply UX bug.
|
|
2105
|
+
const markReplied = () => dbWrite(() => db.setInboundHandlerStatus({
|
|
2106
|
+
chat_id: chatId, msg_id: msg.message_id, status: 'replied',
|
|
2107
|
+
}), 'set handler_status=replied');
|
|
2108
|
+
|
|
2088
2109
|
// sendReply accepts (text, meta?) with optional extra Telegram params
|
|
2089
2110
|
// pulled out via meta.params (kept separate so meta stays for DB tags).
|
|
2111
|
+
// rc.59: also calls markReplied() so slash-command paths don't leave
|
|
2112
|
+
// handler_status='dispatched' for boot-replay to re-fire later. All
|
|
2113
|
+
// 29 sendReply call sites in handleMessage are slash-command exit
|
|
2114
|
+
// paths — the contract "we sent a response, the inbound is handled"
|
|
2115
|
+
// holds for every one of them.
|
|
2090
2116
|
const sendReply = (replyText, meta = {}) => {
|
|
2091
2117
|
const { params: extraParams = {}, ...metaTags } = meta;
|
|
2118
|
+
markReplied();
|
|
2092
2119
|
return tg(bot, 'sendMessage', {
|
|
2093
2120
|
chat_id: chatId, text: replyText, ...replyOpts(threadId), ...extraParams,
|
|
2094
2121
|
}, { source: 'command-reply', botName: BOT_NAME, model: chatConfig.model, effort: chatConfig.effort, ...metaTags });
|
|
@@ -2697,16 +2724,11 @@ async function handleMessage(sessionKey, chatId, msg, bot) {
|
|
|
2697
2724
|
reactor.setState('THINKING');
|
|
2698
2725
|
}
|
|
2699
2726
|
|
|
2700
|
-
//
|
|
2701
|
-
//
|
|
2702
|
-
//
|
|
2703
|
-
//
|
|
2704
|
-
//
|
|
2705
|
-
// left handler_status stuck at 'dispatched' forever and the next
|
|
2706
|
-
// boot replayed every long turn.
|
|
2707
|
-
const markReplied = () => dbWrite(() => db.setInboundHandlerStatus({
|
|
2708
|
-
chat_id: chatId, msg_id: msg.message_id, status: 'replied',
|
|
2709
|
-
}), 'set handler_status=replied');
|
|
2727
|
+
// markReplied hoisted to top of handleMessage in rc.59 (see
|
|
2728
|
+
// definition near sendReply for context). Slash commands path
|
|
2729
|
+
// through sendReply which now calls it; all the OTHER non-throwing
|
|
2730
|
+
// exit paths below (NO_REPLY, streamed-reply preview-becomes-final,
|
|
2731
|
+
// discard+redeliver, regular reply at end) call it directly.
|
|
2710
2732
|
|
|
2711
2733
|
// 0.8.0 Phase 2 step 1 — AUTOSTEER. If SDK pm is active AND there's
|
|
2712
2734
|
// already an in-flight turn for this session AND autosteer isn't
|