polygram 0.8.0-rc.18 → 0.8.0-rc.19
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/lib/canonical-json.js +44 -0
- package/package.json +1 -1
- package/polygram.js +3 -25
|
@@ -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.19",
|
|
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 and a history skill.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"telegram",
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical-JSON stringification for chat_tool_decisions dedup.
|
|
3
|
+
*
|
|
4
|
+
* Used by polygram.js's canUseTool flow (rc.6 Phase 2 step 6):
|
|
5
|
+
* - lookup key for `chat_tool_decisions match_type='exact'`
|
|
6
|
+
* - input_pattern stored on "Always allow / Always deny" clicks
|
|
7
|
+
*
|
|
8
|
+
* Why canonical: Claude can reorder JSON keys between retries of
|
|
9
|
+
* the same tool call (different SDK versions, different temperature
|
|
10
|
+
* sampling). Without canonicalisation, the dedup digest would
|
|
11
|
+
* differ for semantically-identical calls and the user would see
|
|
12
|
+
* the same approval card twice (v4 plan §6.6 ship-breaker M8
|
|
13
|
+
* mitigation).
|
|
14
|
+
*
|
|
15
|
+
* Properties:
|
|
16
|
+
* - Keys sorted alphabetically at every nesting level
|
|
17
|
+
* - Arrays preserve order (only object keys are sorted)
|
|
18
|
+
* - No whitespace in output
|
|
19
|
+
* - null / undefined / primitive inputs round-trip via JSON.stringify
|
|
20
|
+
*
|
|
21
|
+
* NOT a full JSON canonicalisation spec (RFC 8785 / I-D
|
|
22
|
+
* cyberphone-json-canonicalization-scheme); we don't normalise
|
|
23
|
+
* number representations (1.0 vs 1, exponents) or string escapes.
|
|
24
|
+
* Sufficient for SDK-shaped tool inputs which are well-formed JSON
|
|
25
|
+
* objects with string keys.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
'use strict';
|
|
29
|
+
|
|
30
|
+
function canonicalizeToolInput(input) {
|
|
31
|
+
if (input == null || typeof input !== 'object') {
|
|
32
|
+
return JSON.stringify(input);
|
|
33
|
+
}
|
|
34
|
+
const sortRec = (v) => {
|
|
35
|
+
if (Array.isArray(v)) return v.map(sortRec);
|
|
36
|
+
if (v == null || typeof v !== 'object') return v;
|
|
37
|
+
const out = {};
|
|
38
|
+
for (const k of Object.keys(v).sort()) out[k] = sortRec(v[k]);
|
|
39
|
+
return out;
|
|
40
|
+
};
|
|
41
|
+
return JSON.stringify(sortRec(input));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = { canonicalizeToolInput };
|
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.19",
|
|
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
|
@@ -33,6 +33,7 @@ const { ProcessManager } = require('./lib/process-manager');
|
|
|
33
33
|
const { ProcessManagerSdk } = require('./lib/process-manager-sdk');
|
|
34
34
|
const { createAutosteerBuffer, makePostToolBatchHook } = require('./lib/autosteer-buffer');
|
|
35
35
|
const { makeRouterPolicy, createPmRouter } = require('./lib/pm-router');
|
|
36
|
+
const { canonicalizeToolInput } = require('./lib/canonical-json');
|
|
36
37
|
const agentLoader = require('./lib/agent-loader');
|
|
37
38
|
const USE_SDK = process.env.POLYGRAM_USE_SDK === '1';
|
|
38
39
|
const { createSender } = require('./lib/telegram');
|
|
@@ -1367,31 +1368,8 @@ function safeParse(s) {
|
|
|
1367
1368
|
try { return JSON.parse(s); } catch { return s; }
|
|
1368
1369
|
}
|
|
1369
1370
|
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
* object. Keys sorted alphabetically; no whitespace. Used as the
|
|
1373
|
-
* dedup key for chat_tool_decisions match_type='exact' lookups
|
|
1374
|
-
* and as the input_pattern stored on "Always allow" clicks.
|
|
1375
|
-
*
|
|
1376
|
-
* Why canonical: Claude can reorder JSON keys between retries of
|
|
1377
|
-
* the same tool call (different SDK versions, different temperature
|
|
1378
|
-
* sampling). Without canonicalisation, the dedup digest would
|
|
1379
|
-
* differ for semantically-identical calls and the user would see
|
|
1380
|
-
* the same approval card twice (ship-breaker M8 mitigation).
|
|
1381
|
-
*/
|
|
1382
|
-
function canonicalizeToolInput(input) {
|
|
1383
|
-
if (input == null || typeof input !== 'object') {
|
|
1384
|
-
return JSON.stringify(input);
|
|
1385
|
-
}
|
|
1386
|
-
const sortRec = (v) => {
|
|
1387
|
-
if (Array.isArray(v)) return v.map(sortRec);
|
|
1388
|
-
if (v == null || typeof v !== 'object') return v;
|
|
1389
|
-
const out = {};
|
|
1390
|
-
for (const k of Object.keys(v).sort()) out[k] = sortRec(v[k]);
|
|
1391
|
-
return out;
|
|
1392
|
-
};
|
|
1393
|
-
return JSON.stringify(sortRec(input));
|
|
1394
|
-
}
|
|
1371
|
+
// 0.8.0-rc.18+: canonicalizeToolInput moved to lib/canonical-json.js
|
|
1372
|
+
// for testability. Same function, no behavior change.
|
|
1395
1373
|
|
|
1396
1374
|
/**
|
|
1397
1375
|
* 0.8.0 Phase 2 step 6: SDK canUseTool callback. Hands back to the
|