@openacp/cli 2026.327.5 → 2026.330.2
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 +13 -13
- package/dist/adapter-4U6MC5ZS.js +13 -0
- package/dist/agent-catalog-SZQQERV7.js +10 -0
- package/dist/{agent-dependencies-WS7Z2DFW.js → agent-dependencies-ED2ZTUHG.js} +1 -2
- package/dist/{agent-registry-5LZT7CUB.js → agent-registry-YOGP656W.js} +1 -2
- package/dist/agent-store-5UHZH2XI.js +8 -0
- package/dist/{api-client-AQPNKXI2.js → api-client-XTLRRFPX.js} +1 -2
- package/dist/api-server-5VNYFWJE.js +7 -0
- package/dist/api-server-JLBDKCU4.js +10 -0
- package/dist/{autostart-6JS565RY.js → autostart-CUPZMKKC.js} +3 -4
- package/dist/{chunk-WIIZNPCR.js → chunk-2KT6TROD.js} +12 -33
- package/dist/chunk-2KT6TROD.js.map +1 -0
- package/dist/{chunk-PPSMUECX.js → chunk-2R5XM3ES.js} +2 -2
- package/dist/{chunk-SNPYTMPR.js → chunk-3EWTPOF7.js} +2 -2
- package/dist/{chunk-YEULD3SG.js → chunk-3NAFXVQM.js} +7 -2
- package/dist/{chunk-YEULD3SG.js.map → chunk-3NAFXVQM.js.map} +1 -1
- package/dist/{chunk-A6Y4GZM3.js → chunk-566W6INH.js} +2 -2
- package/dist/{chunk-ODUM3D6X.js → chunk-5HKQCYOI.js} +1 -39
- package/dist/chunk-5HKQCYOI.js.map +1 -0
- package/dist/{plugin-installer-QVJP6VKV.js → chunk-5WGVYX3C.js} +18 -5
- package/dist/chunk-5WGVYX3C.js.map +1 -0
- package/dist/{chunk-XWDW3XBE.js → chunk-5ZNBNIK3.js} +1331 -237
- package/dist/chunk-5ZNBNIK3.js.map +1 -0
- package/dist/{chunk-XIBG7LSL.js → chunk-7RKPIM3E.js} +482 -175
- package/dist/chunk-7RKPIM3E.js.map +1 -0
- package/dist/{chunk-WXVT3AOY.js → chunk-7ZCQF6QM.js} +8 -3
- package/dist/chunk-7ZCQF6QM.js.map +1 -0
- package/dist/{chunk-2YCW3QDV.js → chunk-BTJHGSLM.js} +8 -7
- package/dist/chunk-BTJHGSLM.js.map +1 -0
- package/dist/{chunk-P2G275VD.js → chunk-CFUJGWOP.js} +3 -3
- package/dist/{chunk-RBYBSSGO.js → chunk-FCTC7KDT.js} +2 -2
- package/dist/{chunk-QAQDGPB4.js → chunk-GEOXPGCO.js} +3 -3
- package/dist/{chunk-BLQUXO7S.js → chunk-IZ5UEZF7.js} +27 -2
- package/dist/chunk-IZ5UEZF7.js.map +1 -0
- package/dist/{chunk-4GMLGCF2.js → chunk-KDU3ZEWT.js} +2 -2
- package/dist/{chunk-QWP76EBW.js → chunk-MITTQMGZ.js} +16 -9
- package/dist/chunk-MITTQMGZ.js.map +1 -0
- package/dist/{chunk-HRKAXFWR.js → chunk-MPGEHTGE.js} +9 -9
- package/dist/{chunk-KMMEFXIE.js → chunk-PA6MNBG4.js} +41 -9
- package/dist/chunk-PA6MNBG4.js.map +1 -0
- package/dist/{chunk-BQ6FR32N.js → chunk-QWVHCTCA.js} +2 -2
- package/dist/{chunk-XMMAGAT4.js → chunk-R6KZYF7D.js} +8 -1
- package/dist/{chunk-XMMAGAT4.js.map → chunk-R6KZYF7D.js.map} +1 -1
- package/dist/{chunk-AD3X6DGK.js → chunk-TMVTSWVH.js} +75 -13
- package/dist/chunk-TMVTSWVH.js.map +1 -0
- package/dist/chunk-UWH7KIAA.js +701 -0
- package/dist/chunk-UWH7KIAA.js.map +1 -0
- package/dist/{chunk-SHTGQGAU.js → chunk-V2YZWYXT.js} +3 -3
- package/dist/{chunk-QVMEF6FB.js → chunk-W4LK6WJP.js} +38 -27
- package/dist/chunk-W4LK6WJP.js.map +1 -0
- package/dist/{chunk-S3ZGPPXY.js → chunk-YIGBJFJL.js} +9 -13
- package/dist/{chunk-S3ZGPPXY.js.map → chunk-YIGBJFJL.js.map} +1 -1
- package/dist/cli.js +133 -132
- package/dist/cli.js.map +1 -1
- package/dist/config-KN6NKKPF.js +20 -0
- package/dist/config-editor-76RVZS4B.js +10 -0
- package/dist/{config-registry-CUMNXFGK.js → config-registry-ZXAIJNYB.js} +2 -3
- package/dist/context-NXXW62NJ.js +9 -0
- package/dist/core-plugins-OCHKGCIZ.js +22 -0
- package/dist/{daemon-PXO5QPCR.js → daemon-XFEMMJSZ.js} +4 -5
- package/dist/{dev-loader-DRU3R7ZM.js → dev-loader-7P3HZCIA.js} +1 -3
- package/dist/{dev-loader-DRU3R7ZM.js.map → dev-loader-7P3HZCIA.js.map} +1 -1
- package/dist/doctor-AV6AUO22.js +9 -0
- package/dist/file-service-HHB3JQIO.js +8 -0
- package/dist/index.d.ts +141 -187
- package/dist/index.js +33 -29
- package/dist/index.js.map +1 -1
- package/dist/{install-cloudflared-AN24L4DP.js → install-cloudflared-JRJ4BSOM.js} +3 -4
- package/dist/{install-cloudflared-AN24L4DP.js.map → install-cloudflared-JRJ4BSOM.js.map} +1 -1
- package/dist/{install-context-XPWTFT3J.js → install-context-EHYV5WRY.js} +2 -3
- package/dist/{install-context-XPWTFT3J.js.map → install-context-EHYV5WRY.js.map} +1 -1
- package/dist/{install-jq-CRVDJGF3.js → install-jq-ISTGT263.js} +3 -4
- package/dist/{install-jq-CRVDJGF3.js.map → install-jq-ISTGT263.js.map} +1 -1
- package/dist/{integrate-G6CVXTGT.js → integrate-JIEZYDOR.js} +1 -2
- package/dist/{integrate-G6CVXTGT.js.map → integrate-JIEZYDOR.js.map} +1 -1
- package/dist/{log-LZ7FTRKG.js → log-YZ243M5G.js} +4 -3
- package/dist/{main-3GF3EQTE.js → main-L2M4NTJY.js} +135 -50
- package/dist/main-L2M4NTJY.js.map +1 -0
- package/dist/{menu-YDQ2LWAR.js → menu-ALFN37IR.js} +1 -2
- package/dist/notifications-MO23S7S3.js +8 -0
- package/dist/{plugin-create-5HQRF2ID.js → plugin-create-EHL76ZZG.js} +1 -2
- package/dist/{plugin-create-5HQRF2ID.js.map → plugin-create-EHL76ZZG.js.map} +1 -1
- package/dist/plugin-installer-VSTYZSXC.js +9 -0
- package/dist/{plugin-registry-WB3DR67H.js → plugin-registry-6J3YSFHF.js} +1 -2
- package/dist/{plugin-search-HQ4WQKOF.js → plugin-search-MGKAL5JM.js} +1 -2
- package/dist/{plugin-search-HQ4WQKOF.js.map → plugin-search-MGKAL5JM.js.map} +1 -1
- package/dist/{post-upgrade-3ADZRMYJ.js → post-upgrade-Y26S2ZQ7.js} +6 -7
- package/dist/{post-upgrade-3ADZRMYJ.js.map → post-upgrade-Y26S2ZQ7.js.map} +1 -1
- package/dist/{read-text-file-IRZM3QLM.js → read-text-file-DJBTITIB.js} +1 -2
- package/dist/{registry-client-AVGRE4CF.js → registry-client-GTBWLXYU.js} +1 -2
- package/dist/{security-YNRBW6S7.js → security-2BA265LN.js} +1 -2
- package/dist/{settings-manager-MD2U4ZV2.js → settings-manager-B4UN2LAC.js} +1 -2
- package/dist/{setup-A7VPW46C.js → setup-E6BNEYCS.js} +109 -83
- package/dist/setup-E6BNEYCS.js.map +1 -0
- package/dist/speech-SG62JYIF.js +9 -0
- package/dist/{suggest-7D6B542M.js → suggest-RST5VOHB.js} +1 -3
- package/dist/{suggest-7D6B542M.js.map → suggest-RST5VOHB.js.map} +1 -1
- package/dist/telegram-EAVRDNFU.js +7 -0
- package/dist/tunnel-HWJ27WDH.js +7 -0
- package/dist/{tunnel-service-QJPUYEKU.js → tunnel-service-ZMO4THKE.js} +90 -11
- package/dist/tunnel-service-ZMO4THKE.js.map +1 -0
- package/dist/{validators-WSTBNKRW.js → validators-GITLOFXC.js} +1 -2
- package/dist/{version-NQZBM5M7.js → version-AXXV6IV2.js} +1 -2
- package/package.json +1 -3
- package/dist/adapter-JQFQ3JAO.js +0 -15
- package/dist/adapter-UORRGHNH.js +0 -1030
- package/dist/adapter-UORRGHNH.js.map +0 -1
- package/dist/agent-catalog-YHBFERYO.js +0 -11
- package/dist/agent-store-VSHNY5GT.js +0 -9
- package/dist/api-server-7G3ZUZRM.js +0 -8
- package/dist/api-server-CAYNPUF2.js +0 -11
- package/dist/chunk-2YCW3QDV.js.map +0 -1
- package/dist/chunk-32LVIEPW.js +0 -477
- package/dist/chunk-32LVIEPW.js.map +0 -1
- package/dist/chunk-AD3X6DGK.js.map +0 -1
- package/dist/chunk-BLQUXO7S.js.map +0 -1
- package/dist/chunk-KMMEFXIE.js.map +0 -1
- package/dist/chunk-ODUM3D6X.js.map +0 -1
- package/dist/chunk-QVMEF6FB.js.map +0 -1
- package/dist/chunk-QWP76EBW.js.map +0 -1
- package/dist/chunk-VUNV25KB.js +0 -16
- package/dist/chunk-WIIZNPCR.js.map +0 -1
- package/dist/chunk-WXVT3AOY.js.map +0 -1
- package/dist/chunk-XIBG7LSL.js.map +0 -1
- package/dist/chunk-XWDW3XBE.js.map +0 -1
- package/dist/chunk-ZHGPZBS4.js +0 -49
- package/dist/chunk-ZHGPZBS4.js.map +0 -1
- package/dist/chunk-ZNSO2QVC.js +0 -124
- package/dist/chunk-ZNSO2QVC.js.map +0 -1
- package/dist/config-I4FMCJGZ.js +0 -15
- package/dist/config-editor-7PKW42GZ.js +0 -11
- package/dist/context-XM6E22LM.js +0 -10
- package/dist/core-plugins-Y5US6RED.js +0 -23
- package/dist/dist-UHQK5CXN.js +0 -21151
- package/dist/dist-UHQK5CXN.js.map +0 -1
- package/dist/doctor-QZQAP46W.js +0 -10
- package/dist/file-service-EUODJAIT.js +0 -9
- package/dist/main-3GF3EQTE.js.map +0 -1
- package/dist/notifications-D5BRDNSU.js +0 -9
- package/dist/plugin-installer-QVJP6VKV.js.map +0 -1
- package/dist/setup-A7VPW46C.js.map +0 -1
- package/dist/slack-2XNWBOWH.js +0 -8
- package/dist/speech-2GHQNRIO.js +0 -9
- package/dist/telegram-E65IWFBW.js +0 -8
- package/dist/tunnel-45HA72MB.js +0 -8
- package/dist/tunnel-service-QJPUYEKU.js.map +0 -1
- package/dist/version-NQZBM5M7.js.map +0 -1
- /package/dist/{adapter-JQFQ3JAO.js.map → adapter-4U6MC5ZS.js.map} +0 -0
- /package/dist/{agent-catalog-YHBFERYO.js.map → agent-catalog-SZQQERV7.js.map} +0 -0
- /package/dist/{agent-dependencies-WS7Z2DFW.js.map → agent-dependencies-ED2ZTUHG.js.map} +0 -0
- /package/dist/{agent-registry-5LZT7CUB.js.map → agent-registry-YOGP656W.js.map} +0 -0
- /package/dist/{agent-store-VSHNY5GT.js.map → agent-store-5UHZH2XI.js.map} +0 -0
- /package/dist/{api-client-AQPNKXI2.js.map → api-client-XTLRRFPX.js.map} +0 -0
- /package/dist/{api-server-7G3ZUZRM.js.map → api-server-5VNYFWJE.js.map} +0 -0
- /package/dist/{api-server-CAYNPUF2.js.map → api-server-JLBDKCU4.js.map} +0 -0
- /package/dist/{autostart-6JS565RY.js.map → autostart-CUPZMKKC.js.map} +0 -0
- /package/dist/{chunk-PPSMUECX.js.map → chunk-2R5XM3ES.js.map} +0 -0
- /package/dist/{chunk-SNPYTMPR.js.map → chunk-3EWTPOF7.js.map} +0 -0
- /package/dist/{chunk-A6Y4GZM3.js.map → chunk-566W6INH.js.map} +0 -0
- /package/dist/{chunk-P2G275VD.js.map → chunk-CFUJGWOP.js.map} +0 -0
- /package/dist/{chunk-RBYBSSGO.js.map → chunk-FCTC7KDT.js.map} +0 -0
- /package/dist/{chunk-QAQDGPB4.js.map → chunk-GEOXPGCO.js.map} +0 -0
- /package/dist/{chunk-4GMLGCF2.js.map → chunk-KDU3ZEWT.js.map} +0 -0
- /package/dist/{chunk-HRKAXFWR.js.map → chunk-MPGEHTGE.js.map} +0 -0
- /package/dist/{chunk-BQ6FR32N.js.map → chunk-QWVHCTCA.js.map} +0 -0
- /package/dist/{chunk-SHTGQGAU.js.map → chunk-V2YZWYXT.js.map} +0 -0
- /package/dist/{chunk-VUNV25KB.js.map → config-KN6NKKPF.js.map} +0 -0
- /package/dist/{config-I4FMCJGZ.js.map → config-editor-76RVZS4B.js.map} +0 -0
- /package/dist/{config-editor-7PKW42GZ.js.map → config-registry-ZXAIJNYB.js.map} +0 -0
- /package/dist/{config-registry-CUMNXFGK.js.map → context-NXXW62NJ.js.map} +0 -0
- /package/dist/{context-XM6E22LM.js.map → core-plugins-OCHKGCIZ.js.map} +0 -0
- /package/dist/{core-plugins-Y5US6RED.js.map → daemon-XFEMMJSZ.js.map} +0 -0
- /package/dist/{daemon-PXO5QPCR.js.map → doctor-AV6AUO22.js.map} +0 -0
- /package/dist/{doctor-QZQAP46W.js.map → file-service-HHB3JQIO.js.map} +0 -0
- /package/dist/{file-service-EUODJAIT.js.map → log-YZ243M5G.js.map} +0 -0
- /package/dist/{log-LZ7FTRKG.js.map → menu-ALFN37IR.js.map} +0 -0
- /package/dist/{menu-YDQ2LWAR.js.map → notifications-MO23S7S3.js.map} +0 -0
- /package/dist/{notifications-D5BRDNSU.js.map → plugin-installer-VSTYZSXC.js.map} +0 -0
- /package/dist/{plugin-registry-WB3DR67H.js.map → plugin-registry-6J3YSFHF.js.map} +0 -0
- /package/dist/{read-text-file-IRZM3QLM.js.map → read-text-file-DJBTITIB.js.map} +0 -0
- /package/dist/{registry-client-AVGRE4CF.js.map → registry-client-GTBWLXYU.js.map} +0 -0
- /package/dist/{security-YNRBW6S7.js.map → security-2BA265LN.js.map} +0 -0
- /package/dist/{settings-manager-MD2U4ZV2.js.map → settings-manager-B4UN2LAC.js.map} +0 -0
- /package/dist/{slack-2XNWBOWH.js.map → speech-SG62JYIF.js.map} +0 -0
- /package/dist/{speech-2GHQNRIO.js.map → telegram-EAVRDNFU.js.map} +0 -0
- /package/dist/{telegram-E65IWFBW.js.map → tunnel-HWJ27WDH.js.map} +0 -0
- /package/dist/{tunnel-45HA72MB.js.map → validators-GITLOFXC.js.map} +0 -0
- /package/dist/{validators-WSTBNKRW.js.map → version-AXXV6IV2.js.map} +0 -0
|
@@ -7,21 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-AFKX424Q.js";
|
|
8
8
|
import {
|
|
9
9
|
DoctorEngine
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import {
|
|
12
|
-
BaseRenderer,
|
|
13
|
-
MessagingAdapter,
|
|
14
|
-
evaluateNoise,
|
|
15
|
-
extractContentText,
|
|
16
|
-
formatTokens,
|
|
17
|
-
formatToolSummary,
|
|
18
|
-
formatToolTitle,
|
|
19
|
-
progressBar,
|
|
20
|
-
resolveToolIcon,
|
|
21
|
-
splitMessage,
|
|
22
|
-
stripCodeFences,
|
|
23
|
-
truncateContent
|
|
24
|
-
} from "./chunk-32LVIEPW.js";
|
|
10
|
+
} from "./chunk-GEOXPGCO.js";
|
|
25
11
|
import {
|
|
26
12
|
CheckpointReader,
|
|
27
13
|
DEFAULT_MAX_TOKENS
|
|
@@ -31,10 +17,10 @@ import {
|
|
|
31
17
|
getSafeFields,
|
|
32
18
|
isHotReloadable,
|
|
33
19
|
resolveOptions
|
|
34
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-5HKQCYOI.js";
|
|
35
21
|
import {
|
|
36
22
|
createChildLogger
|
|
37
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-R6KZYF7D.js";
|
|
38
24
|
|
|
39
25
|
// src/plugins/telegram/adapter.ts
|
|
40
26
|
import { Bot, InputFile } from "grammy";
|
|
@@ -79,6 +65,266 @@ function buildDeepLink(chatId, threadId, messageId) {
|
|
|
79
65
|
// src/plugins/telegram/commands/new-session.ts
|
|
80
66
|
import { InlineKeyboard as InlineKeyboard2 } from "grammy";
|
|
81
67
|
|
|
68
|
+
// src/core/adapter-primitives/format-types.ts
|
|
69
|
+
var STATUS_ICONS = {
|
|
70
|
+
pending: "\u23F3",
|
|
71
|
+
in_progress: "\u{1F504}",
|
|
72
|
+
completed: "\u2705",
|
|
73
|
+
failed: "\u274C",
|
|
74
|
+
cancelled: "\u{1F6AB}",
|
|
75
|
+
running: "\u{1F504}",
|
|
76
|
+
done: "\u2705",
|
|
77
|
+
error: "\u274C"
|
|
78
|
+
};
|
|
79
|
+
var KIND_ICONS = {
|
|
80
|
+
read: "\u{1F4D6}",
|
|
81
|
+
edit: "\u270F\uFE0F",
|
|
82
|
+
write: "\u270F\uFE0F",
|
|
83
|
+
delete: "\u{1F5D1}\uFE0F",
|
|
84
|
+
execute: "\u25B6\uFE0F",
|
|
85
|
+
command: "\u25B6\uFE0F",
|
|
86
|
+
bash: "\u25B6\uFE0F",
|
|
87
|
+
terminal: "\u25B6\uFE0F",
|
|
88
|
+
search: "\u{1F50D}",
|
|
89
|
+
web: "\u{1F310}",
|
|
90
|
+
fetch: "\u{1F310}",
|
|
91
|
+
agent: "\u{1F9E0}",
|
|
92
|
+
think: "\u{1F9E0}",
|
|
93
|
+
install: "\u{1F4E6}",
|
|
94
|
+
move: "\u{1F4E6}",
|
|
95
|
+
other: "\u{1F6E0}\uFE0F"
|
|
96
|
+
};
|
|
97
|
+
var KIND_LABELS = {
|
|
98
|
+
read: "Read",
|
|
99
|
+
edit: "Edit",
|
|
100
|
+
write: "Write",
|
|
101
|
+
delete: "Delete",
|
|
102
|
+
execute: "Run",
|
|
103
|
+
bash: "Bash",
|
|
104
|
+
command: "Run",
|
|
105
|
+
terminal: "Terminal",
|
|
106
|
+
search: "Search",
|
|
107
|
+
web: "Web",
|
|
108
|
+
fetch: "Fetch",
|
|
109
|
+
agent: "Agent",
|
|
110
|
+
think: "Agent",
|
|
111
|
+
install: "Install",
|
|
112
|
+
move: "Move"
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// src/core/adapter-primitives/format-utils.ts
|
|
116
|
+
function progressBar(ratio, length = 10) {
|
|
117
|
+
const filled = Math.round(Math.min(ratio, 1) * length);
|
|
118
|
+
return "\u2593".repeat(filled) + "\u2591".repeat(length - filled);
|
|
119
|
+
}
|
|
120
|
+
function formatTokens(n) {
|
|
121
|
+
if (n >= 1e6) {
|
|
122
|
+
const m = n / 1e6;
|
|
123
|
+
return m % 1 === 0 ? `${m}M` : `${parseFloat(m.toFixed(1))}M`;
|
|
124
|
+
}
|
|
125
|
+
if (n >= 1e3) {
|
|
126
|
+
const k = n / 1e3;
|
|
127
|
+
return k % 1 === 0 ? `${k}k` : `${parseFloat(k.toFixed(1))}k`;
|
|
128
|
+
}
|
|
129
|
+
return String(n);
|
|
130
|
+
}
|
|
131
|
+
function stripCodeFences(text) {
|
|
132
|
+
return text.replace(/```\w*\n?/g, "").replace(/```$/gm, "").trim();
|
|
133
|
+
}
|
|
134
|
+
function truncateContent(text, maxLen) {
|
|
135
|
+
if (text.length <= maxLen) return text;
|
|
136
|
+
return text.slice(0, maxLen) + "\n\u2026 (truncated)";
|
|
137
|
+
}
|
|
138
|
+
function splitMessage(text, maxLength) {
|
|
139
|
+
if (text.length <= maxLength) return [text];
|
|
140
|
+
const chunks = [];
|
|
141
|
+
let remaining = text;
|
|
142
|
+
while (remaining.length > 0) {
|
|
143
|
+
if (remaining.length <= maxLength) {
|
|
144
|
+
chunks.push(remaining);
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
const wouldLeaveSmall = remaining.length < maxLength * 1.3;
|
|
148
|
+
const searchLimit = wouldLeaveSmall ? Math.floor(remaining.length / 2) + 300 : maxLength;
|
|
149
|
+
const threshold = maxLength * 0.2;
|
|
150
|
+
let splitAt = remaining.lastIndexOf("\n\n", searchLimit);
|
|
151
|
+
if (splitAt === -1 || splitAt < threshold) {
|
|
152
|
+
splitAt = remaining.lastIndexOf("\n", searchLimit);
|
|
153
|
+
}
|
|
154
|
+
if (splitAt === -1 || splitAt < threshold) {
|
|
155
|
+
splitAt = searchLimit;
|
|
156
|
+
}
|
|
157
|
+
const candidate = remaining.slice(0, splitAt);
|
|
158
|
+
const fences = candidate.match(/```/g);
|
|
159
|
+
if (fences && fences.length % 2 !== 0) {
|
|
160
|
+
const closingFence = remaining.indexOf("```", splitAt);
|
|
161
|
+
if (closingFence !== -1) {
|
|
162
|
+
const afterFence = remaining.indexOf("\n", closingFence + 3);
|
|
163
|
+
const fenceSplit = afterFence !== -1 ? afterFence + 1 : closingFence + 3;
|
|
164
|
+
if (fenceSplit <= maxLength * 2) {
|
|
165
|
+
splitAt = fenceSplit;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
chunks.push(remaining.slice(0, splitAt));
|
|
170
|
+
remaining = remaining.slice(splitAt).replace(/^\n+/, "");
|
|
171
|
+
}
|
|
172
|
+
return chunks;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// src/core/adapter-primitives/message-formatter.ts
|
|
176
|
+
function extractContentText(content, depth = 0) {
|
|
177
|
+
if (!content || depth > 5) return "";
|
|
178
|
+
if (typeof content === "string") return content;
|
|
179
|
+
if (Array.isArray(content)) {
|
|
180
|
+
return content.map((c) => extractContentText(c, depth + 1)).filter(Boolean).join("\n");
|
|
181
|
+
}
|
|
182
|
+
if (typeof content !== "object") return String(content);
|
|
183
|
+
const obj = content;
|
|
184
|
+
if (obj.text && typeof obj.text === "string") return obj.text;
|
|
185
|
+
if (obj.content) {
|
|
186
|
+
if (typeof obj.content === "string") return obj.content;
|
|
187
|
+
if (Array.isArray(obj.content)) {
|
|
188
|
+
return obj.content.map((c) => extractContentText(c, depth + 1)).filter(Boolean).join("\n");
|
|
189
|
+
}
|
|
190
|
+
return extractContentText(obj.content, depth + 1);
|
|
191
|
+
}
|
|
192
|
+
if (obj.input) return extractContentText(obj.input, depth + 1);
|
|
193
|
+
if (obj.output) return extractContentText(obj.output, depth + 1);
|
|
194
|
+
const keys = Object.keys(obj).filter((k) => k !== "type");
|
|
195
|
+
if (keys.length === 0) return "";
|
|
196
|
+
try {
|
|
197
|
+
return JSON.stringify(obj, null, 2);
|
|
198
|
+
} catch {
|
|
199
|
+
return "";
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
function parseRawInput(rawInput) {
|
|
203
|
+
try {
|
|
204
|
+
if (typeof rawInput === "string") {
|
|
205
|
+
return JSON.parse(rawInput);
|
|
206
|
+
}
|
|
207
|
+
if (typeof rawInput === "object" && rawInput !== null) {
|
|
208
|
+
return rawInput;
|
|
209
|
+
}
|
|
210
|
+
} catch {
|
|
211
|
+
}
|
|
212
|
+
return {};
|
|
213
|
+
}
|
|
214
|
+
function formatToolSummary(name, rawInput, displaySummary) {
|
|
215
|
+
if (displaySummary && typeof displaySummary === "string") {
|
|
216
|
+
return displaySummary;
|
|
217
|
+
}
|
|
218
|
+
const args = parseRawInput(rawInput);
|
|
219
|
+
const lowerName = name.toLowerCase();
|
|
220
|
+
if (lowerName === "read") {
|
|
221
|
+
const fp = args.file_path ?? args.filePath ?? "";
|
|
222
|
+
const limit = args.limit ? ` (${args.limit} lines)` : "";
|
|
223
|
+
return fp ? `\u{1F4D6} Read ${fp}${limit}` : `\u{1F527} ${name}`;
|
|
224
|
+
}
|
|
225
|
+
if (lowerName === "edit") {
|
|
226
|
+
const fp = args.file_path ?? args.filePath ?? "";
|
|
227
|
+
return fp ? `\u270F\uFE0F Edit ${fp}` : `\u{1F527} ${name}`;
|
|
228
|
+
}
|
|
229
|
+
if (lowerName === "write") {
|
|
230
|
+
const fp = args.file_path ?? args.filePath ?? "";
|
|
231
|
+
return fp ? `\u{1F4DD} Write ${fp}` : `\u{1F527} ${name}`;
|
|
232
|
+
}
|
|
233
|
+
if (lowerName === "bash" || lowerName === "terminal") {
|
|
234
|
+
const cmd = String(args.command ?? args.cmd ?? "").slice(0, 60);
|
|
235
|
+
return cmd ? `\u25B6\uFE0F Run: ${cmd}` : `\u25B6\uFE0F Terminal`;
|
|
236
|
+
}
|
|
237
|
+
if (lowerName === "grep") {
|
|
238
|
+
const pattern = args.pattern ?? "";
|
|
239
|
+
const path2 = args.path ?? "";
|
|
240
|
+
return pattern ? `\u{1F50D} Grep "${pattern}"${path2 ? ` in ${path2}` : ""}` : `\u{1F527} ${name}`;
|
|
241
|
+
}
|
|
242
|
+
if (lowerName === "glob") {
|
|
243
|
+
const pattern = args.pattern ?? "";
|
|
244
|
+
return pattern ? `\u{1F50D} Glob ${pattern}` : `\u{1F527} ${name}`;
|
|
245
|
+
}
|
|
246
|
+
if (lowerName === "agent") {
|
|
247
|
+
const desc = String(args.description ?? "").slice(0, 60);
|
|
248
|
+
return desc ? `\u{1F9E0} Agent: ${desc}` : `\u{1F527} ${name}`;
|
|
249
|
+
}
|
|
250
|
+
if (lowerName === "webfetch" || lowerName === "web_fetch") {
|
|
251
|
+
const url = String(args.url ?? "").slice(0, 60);
|
|
252
|
+
return url ? `\u{1F310} Fetch ${url}` : `\u{1F527} ${name}`;
|
|
253
|
+
}
|
|
254
|
+
if (lowerName === "websearch" || lowerName === "web_search") {
|
|
255
|
+
const query = String(args.query ?? "").slice(0, 60);
|
|
256
|
+
return query ? `\u{1F310} Search "${query}"` : `\u{1F527} ${name}`;
|
|
257
|
+
}
|
|
258
|
+
return `\u{1F527} ${name}`;
|
|
259
|
+
}
|
|
260
|
+
function formatToolTitle(name, rawInput, displayTitle) {
|
|
261
|
+
if (displayTitle && typeof displayTitle === "string") {
|
|
262
|
+
return displayTitle;
|
|
263
|
+
}
|
|
264
|
+
const args = parseRawInput(rawInput);
|
|
265
|
+
const lowerName = name.toLowerCase();
|
|
266
|
+
if (["read", "edit", "write"].includes(lowerName)) {
|
|
267
|
+
return String(args.file_path ?? args.filePath ?? name);
|
|
268
|
+
}
|
|
269
|
+
if (lowerName === "bash" || lowerName === "terminal") {
|
|
270
|
+
return String(args.command ?? args.cmd ?? name).slice(0, 60);
|
|
271
|
+
}
|
|
272
|
+
if (lowerName === "grep") {
|
|
273
|
+
const pattern = args.pattern ?? "";
|
|
274
|
+
const path2 = args.path ?? "";
|
|
275
|
+
return pattern ? `"${pattern}"${path2 ? ` in ${path2}` : ""}` : name;
|
|
276
|
+
}
|
|
277
|
+
if (lowerName === "glob") {
|
|
278
|
+
return String(args.pattern ?? name);
|
|
279
|
+
}
|
|
280
|
+
if (lowerName === "agent") {
|
|
281
|
+
return String(args.description ?? name).slice(0, 60);
|
|
282
|
+
}
|
|
283
|
+
if (["webfetch", "web_fetch"].includes(lowerName)) {
|
|
284
|
+
return String(args.url ?? name).slice(0, 60);
|
|
285
|
+
}
|
|
286
|
+
if (["websearch", "web_search"].includes(lowerName)) {
|
|
287
|
+
return String(args.query ?? name).slice(0, 60);
|
|
288
|
+
}
|
|
289
|
+
return name;
|
|
290
|
+
}
|
|
291
|
+
function resolveToolIcon(tool) {
|
|
292
|
+
const statusIcon = STATUS_ICONS[tool.status || ""];
|
|
293
|
+
if (statusIcon) return statusIcon;
|
|
294
|
+
const kind = tool.displayKind ?? tool.kind;
|
|
295
|
+
if (kind && KIND_ICONS[kind]) return KIND_ICONS[kind];
|
|
296
|
+
return "\u{1F527}";
|
|
297
|
+
}
|
|
298
|
+
var NOISE_RULES = [
|
|
299
|
+
{
|
|
300
|
+
match: (name) => name.toLowerCase() === "ls",
|
|
301
|
+
action: "hide"
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
match: (_name, kind, rawInput) => {
|
|
305
|
+
if (kind !== "read") return false;
|
|
306
|
+
const args = parseRawInput(rawInput);
|
|
307
|
+
const p = String(args.file_path ?? args.filePath ?? args.path ?? "");
|
|
308
|
+
return p.endsWith("/");
|
|
309
|
+
},
|
|
310
|
+
action: "hide"
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
match: (name) => name.toLowerCase() === "glob",
|
|
314
|
+
action: "hide"
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
match: (name) => name.toLowerCase() === "grep",
|
|
318
|
+
action: "hide"
|
|
319
|
+
}
|
|
320
|
+
];
|
|
321
|
+
function evaluateNoise(name, kind, rawInput) {
|
|
322
|
+
for (const rule of NOISE_RULES) {
|
|
323
|
+
if (rule.match(name, kind, rawInput)) return rule.action;
|
|
324
|
+
}
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
|
|
82
328
|
// src/plugins/telegram/formatting.ts
|
|
83
329
|
function escapeHtml(text) {
|
|
84
330
|
if (!text) return "";
|
|
@@ -171,23 +417,16 @@ function formatPlan(plan) {
|
|
|
171
417
|
return `<b>Plan:</b>
|
|
172
418
|
${lines.join("\n")}`;
|
|
173
419
|
}
|
|
174
|
-
function formatUsage(usage,
|
|
175
|
-
const { tokensUsed, contextSize
|
|
420
|
+
function formatUsage(usage, _verbosity = "medium") {
|
|
421
|
+
const { tokensUsed, contextSize } = usage;
|
|
176
422
|
if (tokensUsed == null) return "\u{1F4CA} Usage data unavailable";
|
|
177
|
-
if (verbosity === "medium") {
|
|
178
|
-
const costStr = cost != null ? ` \xB7 $${cost.toFixed(2)}` : "";
|
|
179
|
-
return `\u{1F4CA} ${formatTokens(tokensUsed)} tokens${costStr}`;
|
|
180
|
-
}
|
|
181
423
|
if (contextSize == null) return `\u{1F4CA} ${formatTokens(tokensUsed)} tokens`;
|
|
182
424
|
const ratio = tokensUsed / contextSize;
|
|
183
425
|
const pct = Math.round(ratio * 100);
|
|
184
426
|
const bar = progressBar(ratio);
|
|
185
427
|
const emoji = pct >= 85 ? "\u26A0\uFE0F" : "\u{1F4CA}";
|
|
186
|
-
|
|
428
|
+
return `${emoji} ${formatTokens(tokensUsed)} / ${formatTokens(contextSize)} tokens
|
|
187
429
|
${bar} ${pct}%`;
|
|
188
|
-
if (cost != null) text += `
|
|
189
|
-
\u{1F4B0} $${cost.toFixed(2)}`;
|
|
190
|
-
return text;
|
|
191
430
|
}
|
|
192
431
|
function splitMessage2(text, maxLength = 3800) {
|
|
193
432
|
return splitMessage(text, maxLength);
|
|
@@ -197,61 +436,105 @@ function renderToolCard(snap) {
|
|
|
197
436
|
const { totalVisible, completedVisible, allComplete } = snap;
|
|
198
437
|
const headerCheck = allComplete ? " \u2705" : "";
|
|
199
438
|
if (totalVisible > 0) {
|
|
200
|
-
sections.push(
|
|
201
|
-
`<b>\u{1F4CB} Tools (${completedVisible}/${totalVisible})</b>${headerCheck}`
|
|
202
|
-
);
|
|
439
|
+
sections.push(`<b>\u{1F4CB} Tools (${completedVisible}/${totalVisible})</b>${headerCheck}`);
|
|
203
440
|
}
|
|
204
|
-
const
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
);
|
|
208
|
-
const
|
|
209
|
-
(
|
|
210
|
-
);
|
|
211
|
-
for (const entry of completed) {
|
|
212
|
-
let line = `${entry.icon} ${escapeHtml(entry.label)}`;
|
|
213
|
-
if (entry.viewerLinks) {
|
|
214
|
-
const links = [];
|
|
215
|
-
const fileName = entry.viewerFilePath?.split("/").pop() ?? "";
|
|
216
|
-
if (entry.viewerLinks.file)
|
|
217
|
-
links.push(
|
|
218
|
-
`\u{1F4C4} <a href="${escapeHtml(entry.viewerLinks.file)}">View ${escapeHtml(fileName || "file")}</a>`
|
|
219
|
-
);
|
|
220
|
-
if (entry.viewerLinks.diff)
|
|
221
|
-
links.push(
|
|
222
|
-
`\u{1F4DD} <a href="${escapeHtml(entry.viewerLinks.diff)}">View diff</a>`
|
|
223
|
-
);
|
|
224
|
-
if (links.length > 0) line += `
|
|
225
|
-
${links.join(" \xB7 ")}`;
|
|
226
|
-
}
|
|
227
|
-
sections.push(line);
|
|
441
|
+
const DONE = /* @__PURE__ */ new Set(["completed", "done", "failed", "error"]);
|
|
442
|
+
const visible = snap.specs.filter((s) => !s.isHidden);
|
|
443
|
+
const completed = visible.filter((s) => DONE.has(s.status));
|
|
444
|
+
const running = visible.filter((s) => !DONE.has(s.status));
|
|
445
|
+
for (const spec of completed) {
|
|
446
|
+
sections.push(renderSpecSection(spec));
|
|
228
447
|
}
|
|
229
448
|
if (snap.planEntries && snap.planEntries.length > 0) {
|
|
230
|
-
const planDone = snap.planEntries.filter(
|
|
231
|
-
(e) => e.status === "completed"
|
|
232
|
-
).length;
|
|
449
|
+
const planDone = snap.planEntries.filter((e) => e.status === "completed").length;
|
|
233
450
|
const planTotal = snap.planEntries.length;
|
|
234
451
|
sections.push(`\u2500\u2500 Plan: ${planDone}/${planTotal} \u2500\u2500`);
|
|
235
|
-
const statusIcon = {
|
|
236
|
-
completed: "\u2705",
|
|
237
|
-
in_progress: "\u{1F504}",
|
|
238
|
-
pending: "\u2B1C"
|
|
239
|
-
};
|
|
452
|
+
const statusIcon = { completed: "\u2705", in_progress: "\u{1F504}", pending: "\u2B1C" };
|
|
240
453
|
for (let i = 0; i < snap.planEntries.length; i++) {
|
|
241
454
|
const e = snap.planEntries[i];
|
|
242
|
-
|
|
243
|
-
sections.push(`${icon} ${i + 1}. ${escapeHtml(e.content)}`);
|
|
455
|
+
sections.push(`${statusIcon[e.status] ?? "\u2B1C"} ${i + 1}. ${escapeHtml(e.content)}`);
|
|
244
456
|
}
|
|
245
457
|
sections.push("\u2500\u2500\u2500\u2500");
|
|
246
458
|
}
|
|
247
|
-
for (const
|
|
248
|
-
sections.push(
|
|
459
|
+
for (const spec of running) {
|
|
460
|
+
sections.push(renderSpecSection(spec));
|
|
249
461
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
462
|
+
return sections.join("\n\n");
|
|
463
|
+
}
|
|
464
|
+
var FILE_KINDS = /* @__PURE__ */ new Set(["read", "edit", "write", "delete"]);
|
|
465
|
+
function shortenTitle(title, kind) {
|
|
466
|
+
if (!FILE_KINDS.has(kind) || !title.includes("/")) return title;
|
|
467
|
+
const parenIdx = title.indexOf(" (");
|
|
468
|
+
const pathPart = parenIdx > 0 ? title.slice(0, parenIdx) : title;
|
|
469
|
+
const rangePart = parenIdx > 0 ? title.slice(parenIdx) : "";
|
|
470
|
+
const fileName = pathPart.split("/").pop() || pathPart;
|
|
471
|
+
return fileName + rangePart;
|
|
472
|
+
}
|
|
473
|
+
function renderSpecSection(spec) {
|
|
474
|
+
const lines = [];
|
|
475
|
+
const DONE = /* @__PURE__ */ new Set(["completed", "done", "failed", "error"]);
|
|
476
|
+
const statusPrefix = spec.status === "error" || spec.status === "failed" ? "\u274C " : DONE.has(spec.status) ? "\u2705 " : "\u{1F504} ";
|
|
477
|
+
const kindLabel = KIND_LABELS[spec.kind];
|
|
478
|
+
const displayTitle = shortenTitle(spec.title, spec.kind);
|
|
479
|
+
const hasUniqueTitle = displayTitle && displayTitle.toLowerCase() !== kindLabel?.toLowerCase() && displayTitle.toLowerCase() !== spec.kind;
|
|
480
|
+
let titleLine;
|
|
481
|
+
if (kindLabel) {
|
|
482
|
+
titleLine = hasUniqueTitle ? `${statusPrefix}${spec.icon} <b>${kindLabel}</b> \xB7 ${escapeHtml(displayTitle)}` : `${statusPrefix}${spec.icon} <b>${kindLabel}</b>`;
|
|
483
|
+
} else {
|
|
484
|
+
titleLine = `${statusPrefix}${spec.icon} ${escapeHtml(displayTitle)}`;
|
|
485
|
+
}
|
|
486
|
+
if (spec.diffStats) {
|
|
487
|
+
const { added, removed } = spec.diffStats;
|
|
488
|
+
if (added > 0 && removed > 0) titleLine += ` \xB7 <i>+${added}/-${removed} lines</i>`;
|
|
489
|
+
else if (added > 0) titleLine += ` \xB7 <i>+${added} lines</i>`;
|
|
490
|
+
else if (removed > 0) titleLine += ` \xB7 <i>-${removed} lines</i>`;
|
|
491
|
+
}
|
|
492
|
+
lines.push(titleLine);
|
|
493
|
+
if (spec.description) lines.push(` <i>${escapeHtml(spec.description)}</i>`);
|
|
494
|
+
if (spec.command) lines.push(` <code>${escapeHtml(spec.command)}</code>`);
|
|
495
|
+
if (spec.inputContent) {
|
|
496
|
+
const truncated = spec.inputContent.length > 800 ? spec.inputContent.slice(0, 797) + "\u2026" : spec.inputContent;
|
|
497
|
+
lines.push(` <pre><code>${escapeHtml(truncated)}</code></pre>`);
|
|
498
|
+
}
|
|
499
|
+
if (spec.outputSummary) lines.push(` \xB7 ${escapeHtml(spec.outputSummary)}`);
|
|
500
|
+
if (spec.outputContent || spec.outputFallbackContent) {
|
|
501
|
+
const raw = spec.outputContent ?? spec.outputFallbackContent;
|
|
502
|
+
const truncated = raw.length > 800 ? raw.slice(0, 797) + "\u2026" : raw;
|
|
503
|
+
lines.push(` <pre><code>${escapeHtml(truncated)}</code></pre>`);
|
|
504
|
+
}
|
|
505
|
+
if (spec.viewerLinks?.file || spec.viewerLinks?.diff || spec.outputViewerLink) {
|
|
506
|
+
const linkParts = [];
|
|
507
|
+
const shortName = displayTitle || kindLabel || spec.kind;
|
|
508
|
+
if (spec.viewerLinks?.file)
|
|
509
|
+
linkParts.push(`<a href="${escapeHtml(spec.viewerLinks.file)}">View ${escapeHtml(shortName)}</a>`);
|
|
510
|
+
if (spec.viewerLinks?.diff)
|
|
511
|
+
linkParts.push(`<a href="${escapeHtml(spec.viewerLinks.diff)}">View diff</a>`);
|
|
512
|
+
if (spec.outputViewerLink)
|
|
513
|
+
linkParts.push(`<a href="${escapeHtml(spec.outputViewerLink)}">View output</a>`);
|
|
514
|
+
lines.push(` ${linkParts.join(" \xB7 ")}`);
|
|
515
|
+
}
|
|
516
|
+
return lines.join("\n");
|
|
517
|
+
}
|
|
518
|
+
var TELEGRAM_MAX_LENGTH = 4096;
|
|
519
|
+
function splitToolCardText(text) {
|
|
520
|
+
if (text.length <= TELEGRAM_MAX_LENGTH) return [text];
|
|
521
|
+
const sections = text.split("\n\n");
|
|
522
|
+
const chunks = [];
|
|
523
|
+
let current = "";
|
|
524
|
+
for (const section of sections) {
|
|
525
|
+
const safeSection = section.length > TELEGRAM_MAX_LENGTH ? section.slice(0, TELEGRAM_MAX_LENGTH - 3) + "..." : section;
|
|
526
|
+
const candidate = current ? `${current}
|
|
527
|
+
|
|
528
|
+
${safeSection}` : safeSection;
|
|
529
|
+
if (candidate.length > TELEGRAM_MAX_LENGTH && current) {
|
|
530
|
+
chunks.push(current);
|
|
531
|
+
current = safeSection;
|
|
532
|
+
} else {
|
|
533
|
+
current = candidate;
|
|
534
|
+
}
|
|
253
535
|
}
|
|
254
|
-
|
|
536
|
+
if (current) chunks.push(current);
|
|
537
|
+
return chunks;
|
|
255
538
|
}
|
|
256
539
|
|
|
257
540
|
// src/plugins/telegram/commands/admin.ts
|
|
@@ -440,6 +723,15 @@ function setupTTSCallbacks(bot, core) {
|
|
|
440
723
|
}
|
|
441
724
|
return;
|
|
442
725
|
}
|
|
726
|
+
if (session.voiceMode !== "on" && !core.speechService?.isTTSAvailable()) {
|
|
727
|
+
try {
|
|
728
|
+
await ctx.answerCallbackQuery({
|
|
729
|
+
text: "\u26A0\uFE0F TTS provider not installed. Use /tts install to set up."
|
|
730
|
+
});
|
|
731
|
+
} catch {
|
|
732
|
+
}
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
443
735
|
const newMode = session.voiceMode === "on" ? "off" : "on";
|
|
444
736
|
session.setVoiceMode(newMode);
|
|
445
737
|
const toastText = newMode === "on" ? "\u{1F50A} Text to Speech enabled" : "\u{1F507} Text to Speech disabled";
|
|
@@ -476,6 +768,15 @@ async function handleTTS(ctx, core) {
|
|
|
476
768
|
}
|
|
477
769
|
const args = ctx.message?.text?.split(/\s+/).slice(1) ?? [];
|
|
478
770
|
const arg = args[0]?.toLowerCase();
|
|
771
|
+
if (arg === "on" || !arg) {
|
|
772
|
+
if (!core.speechService?.isTTSAvailable()) {
|
|
773
|
+
await ctx.reply(
|
|
774
|
+
"\u26A0\uFE0F TTS provider not installed.\n\nUse <code>/tts install</code> to install Edge TTS plugin.",
|
|
775
|
+
{ parse_mode: "HTML" }
|
|
776
|
+
);
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
479
780
|
if (arg === "on") {
|
|
480
781
|
session.setVoiceMode("on");
|
|
481
782
|
await ctx.reply("\u{1F50A} Text to Speech enabled for this session.", {
|
|
@@ -491,33 +792,75 @@ async function handleTTS(ctx, core) {
|
|
|
491
792
|
});
|
|
492
793
|
}
|
|
493
794
|
}
|
|
494
|
-
|
|
795
|
+
async function handleVerbosity(ctx, core) {
|
|
796
|
+
await ctx.reply("\u26A0\uFE0F <code>/verbosity</code> is deprecated. Use <code>/outputmode</code> instead.", { parse_mode: "HTML" });
|
|
797
|
+
await handleOutputMode(ctx, core);
|
|
798
|
+
}
|
|
799
|
+
var OUTPUT_MODE_LABELS = {
|
|
495
800
|
low: "\u{1F507} Low",
|
|
496
801
|
medium: "\u{1F4CA} Medium",
|
|
497
|
-
high: "\u{
|
|
802
|
+
high: "\u{1F50D} High"
|
|
498
803
|
};
|
|
499
|
-
async function
|
|
804
|
+
async function handleOutputMode(ctx, core) {
|
|
500
805
|
const args = ctx.message?.text?.split(/\s+/).slice(1) ?? [];
|
|
501
|
-
const
|
|
502
|
-
|
|
806
|
+
const arg0 = args[0]?.toLowerCase();
|
|
807
|
+
const arg1 = args[1]?.toLowerCase();
|
|
808
|
+
if (arg0 === "session") {
|
|
809
|
+
const chatId = ctx.chat?.id;
|
|
810
|
+
const threadId = ctx.message?.message_thread_id;
|
|
811
|
+
if (!chatId || threadId === void 0) {
|
|
812
|
+
await ctx.reply("\u26A0\uFE0F This command must be used in a session topic.", { parse_mode: "HTML" });
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
815
|
+
const session = core.sessionManager.getSessionByThread(
|
|
816
|
+
"telegram",
|
|
817
|
+
String(threadId)
|
|
818
|
+
);
|
|
819
|
+
if (!session) {
|
|
820
|
+
await ctx.reply("\u26A0\uFE0F No active session found for this topic.", { parse_mode: "HTML" });
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
if (arg1 === "reset") {
|
|
824
|
+
await core.sessionManager.patchRecord(session.id, { outputMode: void 0 });
|
|
825
|
+
await ctx.reply("\u{1F504} Session output mode reset to adapter default.", { parse_mode: "HTML" });
|
|
826
|
+
} else if (arg1 === "low" || arg1 === "medium" || arg1 === "high") {
|
|
827
|
+
await core.sessionManager.patchRecord(session.id, { outputMode: arg1 });
|
|
828
|
+
await ctx.reply(
|
|
829
|
+
`${OUTPUT_MODE_LABELS[arg1]} Session output mode set to <b>${arg1}</b>.`,
|
|
830
|
+
{ parse_mode: "HTML" }
|
|
831
|
+
);
|
|
832
|
+
} else {
|
|
833
|
+
const record = core.sessionManager.getSessionRecord(session.id);
|
|
834
|
+
const current = record?.outputMode ?? "(adapter default)";
|
|
835
|
+
await ctx.reply(
|
|
836
|
+
`\u{1F4CA} Session output mode: <b>${current}</b>
|
|
837
|
+
|
|
838
|
+
Usage: <code>/outputmode session low|medium|high|reset</code>`,
|
|
839
|
+
{ parse_mode: "HTML" }
|
|
840
|
+
);
|
|
841
|
+
}
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
if (arg0 === "low" || arg0 === "medium" || arg0 === "high") {
|
|
503
845
|
await core.configManager.save(
|
|
504
|
-
{ channels: { telegram: {
|
|
505
|
-
"channels.telegram.
|
|
846
|
+
{ channels: { telegram: { outputMode: arg0 } } },
|
|
847
|
+
"channels.telegram.outputMode"
|
|
506
848
|
);
|
|
507
849
|
await ctx.reply(
|
|
508
|
-
`${
|
|
850
|
+
`${OUTPUT_MODE_LABELS[arg0]} Output mode set to <b>${arg0}</b>.`,
|
|
509
851
|
{ parse_mode: "HTML" }
|
|
510
852
|
);
|
|
511
853
|
} else {
|
|
512
|
-
const current = core.configManager.get().channels?.telegram?.
|
|
854
|
+
const current = core.configManager.get().channels?.telegram?.outputMode ?? "medium";
|
|
513
855
|
await ctx.reply(
|
|
514
|
-
`\u{1F4CA} Current
|
|
856
|
+
`\u{1F4CA} Current output mode: <b>${current}</b>
|
|
515
857
|
|
|
516
|
-
Usage: <code>/
|
|
858
|
+
Usage: <code>/outputmode low|medium|high</code>
|
|
859
|
+
Session override: <code>/outputmode session low|medium|high|reset</code>
|
|
517
860
|
|
|
518
|
-
\u2022 <b>low</b> \u2014 minimal
|
|
519
|
-
\u2022 <b>medium</b> \u2014 balanced (default)
|
|
520
|
-
\u2022 <b>high</b> \u2014 full detail
|
|
861
|
+
\u2022 <b>low</b> \u2014 minimal: title only
|
|
862
|
+
\u2022 <b>medium</b> \u2014 balanced: description + output summary (default)
|
|
863
|
+
\u2022 <b>high</b> \u2014 full detail: inline output, IN/OUT blocks`,
|
|
521
864
|
{ parse_mode: "HTML" }
|
|
522
865
|
);
|
|
523
866
|
}
|
|
@@ -527,12 +870,12 @@ function setupVerbosityCallbacks(bot, core) {
|
|
|
527
870
|
const level = ctx.callbackQuery.data.slice(3);
|
|
528
871
|
if (level !== "low" && level !== "medium" && level !== "high") return;
|
|
529
872
|
await core.configManager.save(
|
|
530
|
-
{ channels: { telegram: {
|
|
531
|
-
"channels.telegram.
|
|
873
|
+
{ channels: { telegram: { outputMode: level } } },
|
|
874
|
+
"channels.telegram.outputMode"
|
|
532
875
|
);
|
|
533
876
|
try {
|
|
534
877
|
await ctx.answerCallbackQuery({
|
|
535
|
-
text: `${
|
|
878
|
+
text: `${OUTPUT_MODE_LABELS[level]} Output mode: ${level}`
|
|
536
879
|
});
|
|
537
880
|
} catch {
|
|
538
881
|
}
|
|
@@ -546,7 +889,7 @@ async function handleUpdate(ctx, core) {
|
|
|
546
889
|
);
|
|
547
890
|
return;
|
|
548
891
|
}
|
|
549
|
-
const { getCurrentVersion, getLatestVersion, compareVersions, runUpdate } = await import("./version-
|
|
892
|
+
const { getCurrentVersion, getLatestVersion, compareVersions, runUpdate } = await import("./version-AXXV6IV2.js");
|
|
550
893
|
const current = getCurrentVersion();
|
|
551
894
|
const statusMsg = await ctx.reply(
|
|
552
895
|
`\u{1F50D} Checking for updates... (current: v${escapeHtml(current)})`,
|
|
@@ -1290,9 +1633,22 @@ async function handleArchive(ctx, core) {
|
|
|
1290
1633
|
if (!threadId) return;
|
|
1291
1634
|
const session = core.sessionManager.getSessionByThread("telegram", String(threadId));
|
|
1292
1635
|
const record = !session ? core.sessionManager.getRecordByThread("telegram", String(threadId)) : void 0;
|
|
1293
|
-
|
|
1636
|
+
if (!session && !record) {
|
|
1637
|
+
await ctx.reply("This topic is not linked to a session.", { parse_mode: "HTML" });
|
|
1638
|
+
return;
|
|
1639
|
+
}
|
|
1640
|
+
const identifier = session?.id ?? record?.sessionId;
|
|
1641
|
+
if (!identifier) {
|
|
1642
|
+
await ctx.reply("Could not determine session for this topic.", { parse_mode: "HTML" });
|
|
1643
|
+
return;
|
|
1644
|
+
}
|
|
1645
|
+
const status = session?.status ?? record?.status;
|
|
1646
|
+
if (status === "initializing") {
|
|
1647
|
+
await ctx.reply("Cannot archive a session that is still initializing. Wait for it to become active.", { parse_mode: "HTML" });
|
|
1648
|
+
return;
|
|
1649
|
+
}
|
|
1294
1650
|
await ctx.reply(
|
|
1295
|
-
"\u26A0\uFE0F <b>Archive this session?</b>\n\nThis will:\n\u2022 Delete this topic and
|
|
1651
|
+
"\u26A0\uFE0F <b>Archive this session?</b>\n\nThis will:\n\u2022 Delete this topic and recreate it (clearing chat history)\n\u2022 The agent session will keep running\n\n<i>Chat history cannot be recovered.</i>",
|
|
1296
1652
|
{
|
|
1297
1653
|
parse_mode: "HTML",
|
|
1298
1654
|
reply_markup: new InlineKeyboard3().text("\u{1F5D1} Yes, archive", `ar:yes:${identifier}`).text("\u274C Cancel", `ar:no:${identifier}`)
|
|
@@ -1312,37 +1668,21 @@ async function handleArchiveConfirm(ctx, core, chatId) {
|
|
|
1312
1668
|
await ctx.editMessageText("Archive cancelled.", { parse_mode: "HTML" });
|
|
1313
1669
|
return;
|
|
1314
1670
|
}
|
|
1315
|
-
await ctx.editMessageText("\u{1F504} Archiving...", { parse_mode: "HTML" });
|
|
1316
|
-
if (identifier.startsWith("topic:")) {
|
|
1317
|
-
const topicId = Number(identifier.slice("topic:".length));
|
|
1318
|
-
try {
|
|
1319
|
-
await ctx.api.deleteForumTopic(chatId, topicId);
|
|
1320
|
-
core.notificationManager.notifyAll({
|
|
1321
|
-
sessionId: "system",
|
|
1322
|
-
sessionName: `Orphan topic #${topicId}`,
|
|
1323
|
-
type: "completed",
|
|
1324
|
-
summary: `Orphan topic #${topicId} archived and deleted.`
|
|
1325
|
-
});
|
|
1326
|
-
} catch (err) {
|
|
1327
|
-
core.notificationManager.notifyAll({
|
|
1328
|
-
sessionId: "system",
|
|
1329
|
-
sessionName: `Orphan topic #${topicId}`,
|
|
1330
|
-
type: "error",
|
|
1331
|
-
summary: `Failed to delete orphan topic #${topicId}: ${err.message}`
|
|
1332
|
-
});
|
|
1333
|
-
}
|
|
1334
|
-
return;
|
|
1335
|
-
}
|
|
1336
1671
|
const result = await core.archiveSession(identifier);
|
|
1337
1672
|
if (result.ok) {
|
|
1338
|
-
core.
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1673
|
+
const adapter = core.adapters.get("telegram");
|
|
1674
|
+
if (adapter) {
|
|
1675
|
+
try {
|
|
1676
|
+
await adapter.sendMessage(identifier, {
|
|
1677
|
+
type: "text",
|
|
1678
|
+
text: "Chat history cleared. Session is still active \u2014 send a message to continue."
|
|
1679
|
+
});
|
|
1680
|
+
} catch {
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1343
1683
|
} else {
|
|
1344
1684
|
try {
|
|
1345
|
-
await ctx.editMessageText(
|
|
1685
|
+
await ctx.editMessageText(`Failed to archive: <code>${escapeHtml(result.error)}</code>`, { parse_mode: "HTML" });
|
|
1346
1686
|
} catch {
|
|
1347
1687
|
core.notificationManager.notifyAll({
|
|
1348
1688
|
sessionId: identifier,
|
|
@@ -1552,10 +1892,10 @@ Downloading... ${bar} ${percent}%`, { parse_mode: "HTML" });
|
|
|
1552
1892
|
};
|
|
1553
1893
|
const result = await catalog.install(nameOrId, progress);
|
|
1554
1894
|
if (result.ok) {
|
|
1555
|
-
const { getAgentCapabilities } = await import("./agent-dependencies-
|
|
1895
|
+
const { getAgentCapabilities } = await import("./agent-dependencies-ED2ZTUHG.js");
|
|
1556
1896
|
const caps = getAgentCapabilities(result.agentKey);
|
|
1557
1897
|
if (caps.integration) {
|
|
1558
|
-
const { installIntegration } = await import("./integrate-
|
|
1898
|
+
const { installIntegration } = await import("./integrate-JIEZYDOR.js");
|
|
1559
1899
|
const intResult = await installIntegration(result.agentKey, caps.integration);
|
|
1560
1900
|
if (intResult.success) {
|
|
1561
1901
|
try {
|
|
@@ -1625,7 +1965,7 @@ function buildProgressBar(percent) {
|
|
|
1625
1965
|
// src/plugins/telegram/commands/integrate.ts
|
|
1626
1966
|
import { InlineKeyboard as InlineKeyboard5 } from "grammy";
|
|
1627
1967
|
async function handleIntegrate(ctx, _core) {
|
|
1628
|
-
const { listIntegrations } = await import("./integrate-
|
|
1968
|
+
const { listIntegrations } = await import("./integrate-JIEZYDOR.js");
|
|
1629
1969
|
const agents = listIntegrations();
|
|
1630
1970
|
const keyboard = new InlineKeyboard5();
|
|
1631
1971
|
for (const agent of agents) {
|
|
@@ -1658,7 +1998,7 @@ function setupIntegrateCallbacks(bot, core) {
|
|
|
1658
1998
|
} catch {
|
|
1659
1999
|
}
|
|
1660
2000
|
if (data === "i:back") {
|
|
1661
|
-
const { listIntegrations } = await import("./integrate-
|
|
2001
|
+
const { listIntegrations } = await import("./integrate-JIEZYDOR.js");
|
|
1662
2002
|
const agents = listIntegrations();
|
|
1663
2003
|
const keyboard2 = new InlineKeyboard5();
|
|
1664
2004
|
for (const agent of agents) {
|
|
@@ -1678,7 +2018,7 @@ Select an agent to manage its integrations.`,
|
|
|
1678
2018
|
const agentMatch = data.match(/^i:agent:(.+)$/);
|
|
1679
2019
|
if (agentMatch) {
|
|
1680
2020
|
const agentName2 = agentMatch[1];
|
|
1681
|
-
const { getIntegration: getIntegration2 } = await import("./integrate-
|
|
2021
|
+
const { getIntegration: getIntegration2 } = await import("./integrate-JIEZYDOR.js");
|
|
1682
2022
|
const integration2 = getIntegration2(agentName2);
|
|
1683
2023
|
if (!integration2) {
|
|
1684
2024
|
await ctx.reply(`\u274C No integration available for '${escapeHtml(agentName2)}'.`, { parse_mode: "HTML" });
|
|
@@ -1705,7 +2045,7 @@ ${integration2.items.map((i) => `\u2022 <b>${escapeHtml(i.name)}</b> \u2014 ${es
|
|
|
1705
2045
|
const action = actionMatch[1];
|
|
1706
2046
|
const agentName = actionMatch[2];
|
|
1707
2047
|
const itemId = actionMatch[3];
|
|
1708
|
-
const { getIntegration } = await import("./integrate-
|
|
2048
|
+
const { getIntegration } = await import("./integrate-JIEZYDOR.js");
|
|
1709
2049
|
const integration = getIntegration(agentName);
|
|
1710
2050
|
if (!integration) return;
|
|
1711
2051
|
const item = integration.items.find((i) => i.id === itemId);
|
|
@@ -2189,7 +2529,7 @@ Tap to change:`, {
|
|
|
2189
2529
|
await ctx.answerCallbackQuery();
|
|
2190
2530
|
} catch {
|
|
2191
2531
|
}
|
|
2192
|
-
const { buildMenuKeyboard: buildMenuKeyboard3 } = await import("./menu-
|
|
2532
|
+
const { buildMenuKeyboard: buildMenuKeyboard3 } = await import("./menu-ALFN37IR.js");
|
|
2193
2533
|
try {
|
|
2194
2534
|
await ctx.editMessageText(`<b>OpenACP Menu</b>
|
|
2195
2535
|
Choose an action:`, {
|
|
@@ -2511,6 +2851,7 @@ function setupCommands(bot, core, chatId, assistant) {
|
|
|
2511
2851
|
bot.command("archive", (ctx) => handleArchive(ctx, core));
|
|
2512
2852
|
bot.command("text_to_speech", (ctx) => handleTTS(ctx, core));
|
|
2513
2853
|
bot.command("verbosity", (ctx) => handleVerbosity(ctx, core));
|
|
2854
|
+
bot.command("outputmode", (ctx) => handleOutputMode(ctx, core));
|
|
2514
2855
|
bot.command("resume", (ctx) => handleResume(ctx, core, chatId, assistant));
|
|
2515
2856
|
}
|
|
2516
2857
|
function setupAllCallbacks(bot, core, chatId, systemTopicIds, getAssistantSession) {
|
|
@@ -2598,7 +2939,8 @@ var STATIC_COMMANDS = [
|
|
|
2598
2939
|
{ command: "tunnels", description: "List active tunnels" },
|
|
2599
2940
|
{ command: "archive", description: "Archive session topic (recreate with clean history)" },
|
|
2600
2941
|
{ command: "text_to_speech", description: "Toggle Text to Speech (/text_to_speech on, /text_to_speech off)" },
|
|
2601
|
-
{ command: "verbosity", description: "
|
|
2942
|
+
{ command: "verbosity", description: "Deprecated: use /outputmode instead" },
|
|
2943
|
+
{ command: "outputmode", description: "Control output display level (low/medium/high)" },
|
|
2602
2944
|
{ command: "resume", description: "Resume with conversation history from Entire checkpoints" }
|
|
2603
2945
|
];
|
|
2604
2946
|
|
|
@@ -3303,34 +3645,29 @@ function redirectToAssistant(chatId, assistantTopicId) {
|
|
|
3303
3645
|
|
|
3304
3646
|
// src/core/adapter-primitives/primitives/tool-card-state.ts
|
|
3305
3647
|
var DEBOUNCE_MS = 500;
|
|
3648
|
+
var DONE_STATUSES = /* @__PURE__ */ new Set(["completed", "done", "failed", "error"]);
|
|
3306
3649
|
var ToolCardState = class {
|
|
3307
|
-
|
|
3650
|
+
specs = [];
|
|
3308
3651
|
planEntries;
|
|
3309
3652
|
usage;
|
|
3310
3653
|
finalized = false;
|
|
3311
3654
|
isFirstFlush = true;
|
|
3312
3655
|
debounceTimer;
|
|
3313
|
-
verbosity;
|
|
3314
3656
|
onFlush;
|
|
3315
3657
|
constructor(config) {
|
|
3316
|
-
this.verbosity = config.verbosity;
|
|
3317
3658
|
this.onFlush = config.onFlush;
|
|
3318
3659
|
}
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
viewerFilePath: meta.viewerFilePath,
|
|
3331
|
-
hidden
|
|
3332
|
-
};
|
|
3333
|
-
this.entries.push(entry);
|
|
3660
|
+
updateFromSpec(spec) {
|
|
3661
|
+
const existingIdx = this.specs.findIndex((s) => s.id === spec.id);
|
|
3662
|
+
if (existingIdx >= 0) {
|
|
3663
|
+
this.specs[existingIdx] = spec;
|
|
3664
|
+
} else {
|
|
3665
|
+
this.specs.push(spec);
|
|
3666
|
+
}
|
|
3667
|
+
if (this.finalized) {
|
|
3668
|
+
this.onFlush(this.snapshot());
|
|
3669
|
+
return;
|
|
3670
|
+
}
|
|
3334
3671
|
if (this.isFirstFlush) {
|
|
3335
3672
|
this.isFirstFlush = false;
|
|
3336
3673
|
this.flush();
|
|
@@ -3338,20 +3675,10 @@ var ToolCardState = class {
|
|
|
3338
3675
|
this.scheduleFlush();
|
|
3339
3676
|
}
|
|
3340
3677
|
}
|
|
3341
|
-
updateTool(id, status, viewerLinks, viewerFilePath) {
|
|
3342
|
-
if (this.finalized) return;
|
|
3343
|
-
const entry = this.entries.find((e) => e.id === id);
|
|
3344
|
-
if (!entry) return;
|
|
3345
|
-
entry.status = status;
|
|
3346
|
-
entry.icon = resolveToolIcon({ status, kind: entry.kind });
|
|
3347
|
-
if (viewerLinks) entry.viewerLinks = viewerLinks;
|
|
3348
|
-
if (viewerFilePath) entry.viewerFilePath = viewerFilePath;
|
|
3349
|
-
this.scheduleFlush();
|
|
3350
|
-
}
|
|
3351
3678
|
updatePlan(entries) {
|
|
3352
3679
|
if (this.finalized) return;
|
|
3353
3680
|
this.planEntries = entries;
|
|
3354
|
-
if (this.
|
|
3681
|
+
if (this.specs.length === 0 && this.isFirstFlush) {
|
|
3355
3682
|
this.isFirstFlush = false;
|
|
3356
3683
|
this.flush();
|
|
3357
3684
|
} else {
|
|
@@ -3361,7 +3688,7 @@ var ToolCardState = class {
|
|
|
3361
3688
|
appendUsage(usage) {
|
|
3362
3689
|
if (this.finalized) return;
|
|
3363
3690
|
this.usage = usage;
|
|
3364
|
-
this.
|
|
3691
|
+
this.scheduleFlush();
|
|
3365
3692
|
}
|
|
3366
3693
|
finalize() {
|
|
3367
3694
|
if (this.finalized) return;
|
|
@@ -3374,23 +3701,19 @@ var ToolCardState = class {
|
|
|
3374
3701
|
this.clearDebounce();
|
|
3375
3702
|
}
|
|
3376
3703
|
hasContent() {
|
|
3377
|
-
return this.
|
|
3704
|
+
return this.specs.length > 0 || this.planEntries !== void 0;
|
|
3378
3705
|
}
|
|
3379
3706
|
snapshot() {
|
|
3380
|
-
const visible = this.
|
|
3381
|
-
const completedVisible = visible.filter(
|
|
3382
|
-
(e) => e.status === "completed" || e.status === "done"
|
|
3383
|
-
).length;
|
|
3707
|
+
const visible = this.specs.filter((s) => !s.isHidden);
|
|
3708
|
+
const completedVisible = visible.filter((s) => DONE_STATUSES.has(s.status)).length;
|
|
3384
3709
|
const allComplete = visible.length > 0 && completedVisible === visible.length;
|
|
3385
3710
|
return {
|
|
3386
|
-
|
|
3711
|
+
specs: this.specs,
|
|
3387
3712
|
planEntries: this.planEntries,
|
|
3388
3713
|
usage: this.usage,
|
|
3389
|
-
visibleCount: visible.length,
|
|
3390
3714
|
totalVisible: visible.length,
|
|
3391
3715
|
completedVisible,
|
|
3392
|
-
allComplete
|
|
3393
|
-
verbosity: this.verbosity
|
|
3716
|
+
allComplete
|
|
3394
3717
|
};
|
|
3395
3718
|
}
|
|
3396
3719
|
flush() {
|
|
@@ -3412,37 +3735,283 @@ var ToolCardState = class {
|
|
|
3412
3735
|
}
|
|
3413
3736
|
};
|
|
3414
3737
|
|
|
3738
|
+
// src/core/adapter-primitives/stream-accumulator.ts
|
|
3739
|
+
var ToolStateMap = class {
|
|
3740
|
+
entries = /* @__PURE__ */ new Map();
|
|
3741
|
+
pendingUpdates = /* @__PURE__ */ new Map();
|
|
3742
|
+
/**
|
|
3743
|
+
* Creates or updates an entry from a tool_call event.
|
|
3744
|
+
* If a pending update exists for this id, applies it immediately.
|
|
3745
|
+
*/
|
|
3746
|
+
upsert(meta, kind, rawInput) {
|
|
3747
|
+
const isNoise = evaluateNoise(meta.name, kind, rawInput) !== null;
|
|
3748
|
+
const entry = {
|
|
3749
|
+
id: meta.id,
|
|
3750
|
+
name: meta.name,
|
|
3751
|
+
kind,
|
|
3752
|
+
rawInput,
|
|
3753
|
+
content: null,
|
|
3754
|
+
status: meta.status ?? "running",
|
|
3755
|
+
viewerLinks: meta.viewerLinks,
|
|
3756
|
+
displaySummary: meta.displaySummary,
|
|
3757
|
+
displayTitle: meta.displayTitle,
|
|
3758
|
+
displayKind: meta.displayKind,
|
|
3759
|
+
isNoise
|
|
3760
|
+
};
|
|
3761
|
+
this.entries.set(meta.id, entry);
|
|
3762
|
+
const pending = this.pendingUpdates.get(meta.id);
|
|
3763
|
+
if (pending) {
|
|
3764
|
+
this.pendingUpdates.delete(meta.id);
|
|
3765
|
+
this._applyUpdate(entry, pending);
|
|
3766
|
+
}
|
|
3767
|
+
return entry;
|
|
3768
|
+
}
|
|
3769
|
+
/**
|
|
3770
|
+
* Updates an existing entry from a tool_call_update event.
|
|
3771
|
+
* If the entry doesn't exist yet (out-of-order delivery), buffers the update.
|
|
3772
|
+
*/
|
|
3773
|
+
merge(id, status, rawInput, content, viewerLinks, diffStats) {
|
|
3774
|
+
const entry = this.entries.get(id);
|
|
3775
|
+
if (!entry) {
|
|
3776
|
+
this.pendingUpdates.set(id, { status, rawInput, content, viewerLinks, diffStats });
|
|
3777
|
+
return void 0;
|
|
3778
|
+
}
|
|
3779
|
+
this._applyUpdate(entry, { status, rawInput, content, viewerLinks, diffStats });
|
|
3780
|
+
return entry;
|
|
3781
|
+
}
|
|
3782
|
+
_applyUpdate(entry, update) {
|
|
3783
|
+
entry.status = update.status;
|
|
3784
|
+
if (update.rawInput !== void 0) {
|
|
3785
|
+
entry.rawInput = update.rawInput;
|
|
3786
|
+
}
|
|
3787
|
+
if (update.content !== void 0) {
|
|
3788
|
+
entry.content = update.content ?? null;
|
|
3789
|
+
}
|
|
3790
|
+
if (update.viewerLinks !== void 0) {
|
|
3791
|
+
entry.viewerLinks = update.viewerLinks;
|
|
3792
|
+
}
|
|
3793
|
+
if (update.diffStats !== void 0) {
|
|
3794
|
+
entry.diffStats = update.diffStats;
|
|
3795
|
+
}
|
|
3796
|
+
}
|
|
3797
|
+
get(id) {
|
|
3798
|
+
return this.entries.get(id);
|
|
3799
|
+
}
|
|
3800
|
+
clear() {
|
|
3801
|
+
this.entries.clear();
|
|
3802
|
+
this.pendingUpdates.clear();
|
|
3803
|
+
}
|
|
3804
|
+
};
|
|
3805
|
+
var ThoughtBuffer = class {
|
|
3806
|
+
chunks = [];
|
|
3807
|
+
sealed = false;
|
|
3808
|
+
append(chunk) {
|
|
3809
|
+
if (this.sealed) return;
|
|
3810
|
+
this.chunks.push(chunk);
|
|
3811
|
+
}
|
|
3812
|
+
seal() {
|
|
3813
|
+
this.sealed = true;
|
|
3814
|
+
return this.chunks.join("");
|
|
3815
|
+
}
|
|
3816
|
+
getText() {
|
|
3817
|
+
return this.chunks.join("");
|
|
3818
|
+
}
|
|
3819
|
+
isSealed() {
|
|
3820
|
+
return this.sealed;
|
|
3821
|
+
}
|
|
3822
|
+
reset() {
|
|
3823
|
+
this.chunks = [];
|
|
3824
|
+
this.sealed = false;
|
|
3825
|
+
}
|
|
3826
|
+
};
|
|
3827
|
+
|
|
3828
|
+
// src/core/adapter-primitives/display-spec-builder.ts
|
|
3829
|
+
var EXECUTE_KINDS = /* @__PURE__ */ new Set(["execute", "bash", "command", "terminal"]);
|
|
3830
|
+
var INLINE_MAX_LINES = 15;
|
|
3831
|
+
var INLINE_MAX_CHARS = 800;
|
|
3832
|
+
function asRecord(value) {
|
|
3833
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
3834
|
+
return value;
|
|
3835
|
+
}
|
|
3836
|
+
return {};
|
|
3837
|
+
}
|
|
3838
|
+
function capitalize(s) {
|
|
3839
|
+
return s.length === 0 ? s : s[0].toUpperCase() + s.slice(1);
|
|
3840
|
+
}
|
|
3841
|
+
function buildTitle(entry, kind) {
|
|
3842
|
+
if (entry.displayTitle) return entry.displayTitle;
|
|
3843
|
+
if (entry.displaySummary) return entry.displaySummary;
|
|
3844
|
+
const input = asRecord(entry.rawInput);
|
|
3845
|
+
if (kind === "read") {
|
|
3846
|
+
const filePath = typeof input.file_path === "string" ? input.file_path : null;
|
|
3847
|
+
if (filePath) {
|
|
3848
|
+
const startLine = typeof input.start_line === "number" ? input.start_line : null;
|
|
3849
|
+
const endLine = typeof input.end_line === "number" ? input.end_line : null;
|
|
3850
|
+
if (startLine !== null && endLine !== null) return `${filePath} (lines ${startLine}\u2013${endLine})`;
|
|
3851
|
+
if (startLine !== null) return `${filePath} (from line ${startLine})`;
|
|
3852
|
+
const offset = typeof input.offset === "number" ? input.offset : null;
|
|
3853
|
+
const limit = typeof input.limit === "number" ? input.limit : null;
|
|
3854
|
+
if (offset !== null && limit !== null) return `${filePath} (lines ${offset}\u2013${offset + limit - 1})`;
|
|
3855
|
+
if (offset !== null) return `${filePath} (from line ${offset})`;
|
|
3856
|
+
return filePath;
|
|
3857
|
+
}
|
|
3858
|
+
return capitalize(entry.name);
|
|
3859
|
+
}
|
|
3860
|
+
if (kind === "edit" || kind === "write" || kind === "delete") {
|
|
3861
|
+
const filePath = typeof input.file_path === "string" ? input.file_path : typeof input.path === "string" ? input.path : null;
|
|
3862
|
+
if (filePath) return filePath;
|
|
3863
|
+
return capitalize(entry.name);
|
|
3864
|
+
}
|
|
3865
|
+
if (EXECUTE_KINDS.has(kind)) {
|
|
3866
|
+
const description = typeof input.description === "string" ? input.description : null;
|
|
3867
|
+
if (description) return description;
|
|
3868
|
+
const command = typeof input.command === "string" ? input.command : null;
|
|
3869
|
+
if (command) return command.length > 60 ? command.slice(0, 57) + "..." : command;
|
|
3870
|
+
return capitalize(entry.name);
|
|
3871
|
+
}
|
|
3872
|
+
if (kind === "agent") {
|
|
3873
|
+
const skill = typeof input.skill === "string" ? input.skill : null;
|
|
3874
|
+
const description = typeof input.description === "string" ? input.description : null;
|
|
3875
|
+
const subtype = typeof input.subagent_type === "string" ? input.subagent_type : null;
|
|
3876
|
+
if (skill) return skill;
|
|
3877
|
+
if (description) return description.length > 60 ? description.slice(0, 57) + "..." : description;
|
|
3878
|
+
if (subtype) return subtype;
|
|
3879
|
+
return capitalize(entry.name);
|
|
3880
|
+
}
|
|
3881
|
+
if (kind === "search") {
|
|
3882
|
+
const pattern = typeof input.pattern === "string" ? input.pattern : typeof input.query === "string" ? input.query : null;
|
|
3883
|
+
if (pattern) {
|
|
3884
|
+
let title = `${capitalize(entry.name)} "${pattern}"`;
|
|
3885
|
+
const glob = typeof input.glob === "string" ? input.glob : null;
|
|
3886
|
+
const type = typeof input.type === "string" ? input.type : null;
|
|
3887
|
+
if (glob) title += ` (glob: ${glob})`;
|
|
3888
|
+
else if (type) title += ` (type: ${type})`;
|
|
3889
|
+
return title;
|
|
3890
|
+
}
|
|
3891
|
+
return capitalize(entry.name);
|
|
3892
|
+
}
|
|
3893
|
+
if (entry.name.toLowerCase() === "skill" && typeof input.skill === "string" && input.skill) {
|
|
3894
|
+
return input.skill;
|
|
3895
|
+
}
|
|
3896
|
+
return entry.name;
|
|
3897
|
+
}
|
|
3898
|
+
function buildOutputSummary(content) {
|
|
3899
|
+
const lines = content.split("\n").length;
|
|
3900
|
+
return `${lines} line${lines === 1 ? "" : "s"} of output`;
|
|
3901
|
+
}
|
|
3902
|
+
function isTitleFromCommand(title, command) {
|
|
3903
|
+
return title === command || command.length > 60 && title === command.slice(0, 57) + "...";
|
|
3904
|
+
}
|
|
3905
|
+
var DisplaySpecBuilder = class {
|
|
3906
|
+
constructor(tunnelService) {
|
|
3907
|
+
this.tunnelService = tunnelService;
|
|
3908
|
+
}
|
|
3909
|
+
buildToolSpec(entry, mode, sessionContext) {
|
|
3910
|
+
const effectiveKind = entry.displayKind ?? entry.kind;
|
|
3911
|
+
const icon = KIND_ICONS[effectiveKind] ?? KIND_ICONS["other"] ?? "\u{1F6E0}\uFE0F";
|
|
3912
|
+
const title = buildTitle(entry, effectiveKind);
|
|
3913
|
+
const isHidden = entry.isNoise && mode !== "high";
|
|
3914
|
+
const includeMeta = mode !== "low";
|
|
3915
|
+
const input = asRecord(entry.rawInput);
|
|
3916
|
+
const rawDescription = typeof input.description === "string" ? input.description : null;
|
|
3917
|
+
const descLower = rawDescription?.toLowerCase();
|
|
3918
|
+
const description = includeMeta && rawDescription && rawDescription !== title && descLower !== effectiveKind && descLower !== entry.name.toLowerCase() ? rawDescription : null;
|
|
3919
|
+
const rawCommand = EXECUTE_KINDS.has(effectiveKind) && typeof input.command === "string" ? input.command : null;
|
|
3920
|
+
const command = includeMeta && rawCommand && !isTitleFromCommand(title, rawCommand) ? rawCommand : null;
|
|
3921
|
+
const inputContent = null;
|
|
3922
|
+
const content = entry.content;
|
|
3923
|
+
let outputSummary = null;
|
|
3924
|
+
let outputContent = null;
|
|
3925
|
+
let outputViewerLink = void 0;
|
|
3926
|
+
let outputFallbackContent = void 0;
|
|
3927
|
+
if (content && content.trim().length > 0 && includeMeta) {
|
|
3928
|
+
outputSummary = buildOutputSummary(content);
|
|
3929
|
+
const isLong = content.split("\n").length > INLINE_MAX_LINES || content.length > INLINE_MAX_CHARS;
|
|
3930
|
+
if (isLong) {
|
|
3931
|
+
const publicUrl = this.tunnelService?.getPublicUrl();
|
|
3932
|
+
const hasPublicTunnel = !!publicUrl && !publicUrl.startsWith("http://localhost") && !publicUrl.startsWith("http://127.0.0.1");
|
|
3933
|
+
if (this.tunnelService && sessionContext && hasPublicTunnel) {
|
|
3934
|
+
const label = typeof input.command === "string" ? input.command : entry.name;
|
|
3935
|
+
const id = this.tunnelService.getStore().storeOutput(sessionContext.id, label, content);
|
|
3936
|
+
if (id !== null) {
|
|
3937
|
+
outputViewerLink = this.tunnelService.outputUrl(id);
|
|
3938
|
+
}
|
|
3939
|
+
} else if (mode === "high") {
|
|
3940
|
+
outputFallbackContent = content;
|
|
3941
|
+
}
|
|
3942
|
+
} else if (mode === "high") {
|
|
3943
|
+
outputContent = content;
|
|
3944
|
+
}
|
|
3945
|
+
}
|
|
3946
|
+
const diffStats = includeMeta ? entry.diffStats ?? null : null;
|
|
3947
|
+
return {
|
|
3948
|
+
id: entry.id,
|
|
3949
|
+
kind: effectiveKind,
|
|
3950
|
+
icon,
|
|
3951
|
+
title,
|
|
3952
|
+
description,
|
|
3953
|
+
command,
|
|
3954
|
+
inputContent,
|
|
3955
|
+
outputSummary,
|
|
3956
|
+
outputContent,
|
|
3957
|
+
diffStats,
|
|
3958
|
+
viewerLinks: entry.viewerLinks,
|
|
3959
|
+
outputViewerLink,
|
|
3960
|
+
outputFallbackContent,
|
|
3961
|
+
status: entry.status,
|
|
3962
|
+
isNoise: entry.isNoise,
|
|
3963
|
+
isHidden
|
|
3964
|
+
};
|
|
3965
|
+
}
|
|
3966
|
+
buildThoughtSpec(content, mode) {
|
|
3967
|
+
const indicator = "Thinking...";
|
|
3968
|
+
return {
|
|
3969
|
+
indicator,
|
|
3970
|
+
content: mode === "high" ? content : null
|
|
3971
|
+
};
|
|
3972
|
+
}
|
|
3973
|
+
};
|
|
3974
|
+
|
|
3415
3975
|
// src/plugins/telegram/activity.ts
|
|
3416
3976
|
var log10 = createChildLogger({ module: "telegram:activity" });
|
|
3417
3977
|
var THINKING_REFRESH_MS = 15e3;
|
|
3418
3978
|
var THINKING_MAX_MS = 3 * 60 * 1e3;
|
|
3419
3979
|
var ThinkingIndicator = class {
|
|
3420
|
-
constructor(api, chatId, threadId, sendQueue) {
|
|
3980
|
+
constructor(api, chatId, threadId, sendQueue, sessionId = "", tracer = null) {
|
|
3421
3981
|
this.api = api;
|
|
3422
3982
|
this.chatId = chatId;
|
|
3423
3983
|
this.threadId = threadId;
|
|
3424
3984
|
this.sendQueue = sendQueue;
|
|
3985
|
+
this.sessionId = sessionId;
|
|
3986
|
+
this.tracer = tracer;
|
|
3425
3987
|
}
|
|
3426
3988
|
msgId;
|
|
3427
3989
|
sending = false;
|
|
3428
3990
|
dismissed = false;
|
|
3429
3991
|
refreshTimer;
|
|
3430
3992
|
showTime = 0;
|
|
3993
|
+
tracer;
|
|
3431
3994
|
async show() {
|
|
3432
|
-
if (this.
|
|
3995
|
+
if (this.sending || this.dismissed) return;
|
|
3996
|
+
if (this.msgId) return;
|
|
3433
3997
|
this.sending = true;
|
|
3434
3998
|
this.showTime = Date.now();
|
|
3999
|
+
const text = "\u{1F4AD} <i>Thinking...</i>";
|
|
3435
4000
|
try {
|
|
3436
4001
|
const result = await this.sendQueue.enqueue(
|
|
3437
|
-
() => this.api.sendMessage(this.chatId,
|
|
4002
|
+
() => this.api.sendMessage(this.chatId, text, {
|
|
3438
4003
|
message_thread_id: this.threadId,
|
|
3439
4004
|
parse_mode: "HTML",
|
|
3440
4005
|
disable_notification: true
|
|
3441
4006
|
})
|
|
3442
4007
|
);
|
|
3443
|
-
if (result
|
|
3444
|
-
this.msgId
|
|
3445
|
-
this.
|
|
4008
|
+
if (result) {
|
|
4009
|
+
this.tracer?.log("telegram", { action: "thinking:show", sessionId: this.sessionId, msgId: result.message_id });
|
|
4010
|
+
if (this.dismissed) {
|
|
4011
|
+
} else {
|
|
4012
|
+
this.msgId = result.message_id;
|
|
4013
|
+
this.startRefreshTimer();
|
|
4014
|
+
}
|
|
3446
4015
|
}
|
|
3447
4016
|
} catch (err) {
|
|
3448
4017
|
log10.warn({ err }, "ThinkingIndicator.show() failed");
|
|
@@ -3450,11 +4019,27 @@ var ThinkingIndicator = class {
|
|
|
3450
4019
|
this.sending = false;
|
|
3451
4020
|
}
|
|
3452
4021
|
}
|
|
3453
|
-
/**
|
|
3454
|
-
|
|
4022
|
+
/** Edit the indicator message to append a viewer link, then dismiss. */
|
|
4023
|
+
async finalizeWithViewerLink(url) {
|
|
4024
|
+
this.stopRefreshTimer();
|
|
4025
|
+
if (this.msgId && !this.dismissed) {
|
|
4026
|
+
const text = `\u{1F4AD} <i>Thinking...</i> <a href="${escapeHtml(url)}">View thinking</a>`;
|
|
4027
|
+
await this.sendQueue.enqueue(() => {
|
|
4028
|
+
if (!this.msgId) return Promise.resolve(void 0);
|
|
4029
|
+
return this.api.editMessageText(this.chatId, this.msgId, text, { parse_mode: "HTML" });
|
|
4030
|
+
}).catch(() => {
|
|
4031
|
+
});
|
|
4032
|
+
}
|
|
3455
4033
|
this.dismissed = true;
|
|
3456
4034
|
this.msgId = void 0;
|
|
4035
|
+
}
|
|
4036
|
+
/** Dismiss indicator: stops refresh timer. Message is left in chat to reduce API calls. */
|
|
4037
|
+
async dismiss() {
|
|
4038
|
+
if (this.dismissed) return;
|
|
4039
|
+
this.dismissed = true;
|
|
4040
|
+
this.tracer?.log("telegram", { action: "thinking:dismiss", sessionId: this.sessionId });
|
|
3457
4041
|
this.stopRefreshTimer();
|
|
4042
|
+
this.msgId = void 0;
|
|
3458
4043
|
}
|
|
3459
4044
|
/** Reset for a new prompt cycle */
|
|
3460
4045
|
reset() {
|
|
@@ -3468,12 +4053,13 @@ var ThinkingIndicator = class {
|
|
|
3468
4053
|
return;
|
|
3469
4054
|
}
|
|
3470
4055
|
const elapsed = Math.round((Date.now() - this.showTime) / 1e3);
|
|
4056
|
+
const refreshText = `\u{1F4AD} <i>Still thinking... (${elapsed}s)</i>`;
|
|
3471
4057
|
this.sendQueue.enqueue(() => {
|
|
3472
4058
|
if (this.dismissed || !this.msgId) return Promise.resolve(void 0);
|
|
3473
4059
|
return this.api.editMessageText(
|
|
3474
4060
|
this.chatId,
|
|
3475
4061
|
this.msgId,
|
|
3476
|
-
|
|
4062
|
+
refreshText,
|
|
3477
4063
|
{ parse_mode: "HTML" }
|
|
3478
4064
|
);
|
|
3479
4065
|
}).then(() => {
|
|
@@ -3489,13 +4075,14 @@ var ThinkingIndicator = class {
|
|
|
3489
4075
|
}
|
|
3490
4076
|
};
|
|
3491
4077
|
var ToolCard = class {
|
|
3492
|
-
constructor(api, chatId, threadId, sendQueue,
|
|
4078
|
+
constructor(api, chatId, threadId, sendQueue, sessionId = "", tracer = null) {
|
|
3493
4079
|
this.api = api;
|
|
3494
4080
|
this.chatId = chatId;
|
|
3495
4081
|
this.threadId = threadId;
|
|
3496
4082
|
this.sendQueue = sendQueue;
|
|
4083
|
+
this.tracer = tracer;
|
|
4084
|
+
this.sessionId = sessionId;
|
|
3497
4085
|
this.state = new ToolCardState({
|
|
3498
|
-
verbosity,
|
|
3499
4086
|
onFlush: (snapshot) => {
|
|
3500
4087
|
this.flushPromise = this.flushPromise.then(() => this._sendOrEdit(snapshot)).catch(() => {
|
|
3501
4088
|
});
|
|
@@ -3506,11 +4093,11 @@ var ToolCard = class {
|
|
|
3506
4093
|
msgId;
|
|
3507
4094
|
lastSentText;
|
|
3508
4095
|
flushPromise = Promise.resolve();
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
this.state.
|
|
4096
|
+
overflowMsgIds = [];
|
|
4097
|
+
tracer;
|
|
4098
|
+
sessionId;
|
|
4099
|
+
updateFromSpec(spec) {
|
|
4100
|
+
this.state.updateFromSpec(spec);
|
|
3514
4101
|
}
|
|
3515
4102
|
updatePlan(entries) {
|
|
3516
4103
|
this.state.updatePlan(entries);
|
|
@@ -3532,26 +4119,58 @@ var ToolCard = class {
|
|
|
3532
4119
|
return this.msgId;
|
|
3533
4120
|
}
|
|
3534
4121
|
async _sendOrEdit(snapshot) {
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
if (
|
|
3538
|
-
|
|
4122
|
+
let snapshotToRender = snapshot;
|
|
4123
|
+
let fullText = renderToolCard(snapshotToRender);
|
|
4124
|
+
if (fullText.length > 4096) {
|
|
4125
|
+
snapshotToRender = {
|
|
4126
|
+
...snapshot,
|
|
4127
|
+
specs: snapshot.specs.map(
|
|
4128
|
+
(s) => s.outputContent ? { ...s, outputContent: null } : s
|
|
4129
|
+
)
|
|
4130
|
+
};
|
|
4131
|
+
fullText = renderToolCard(snapshotToRender);
|
|
4132
|
+
}
|
|
4133
|
+
if (!fullText) return;
|
|
4134
|
+
if (this.msgId && fullText === this.lastSentText) return;
|
|
4135
|
+
this.lastSentText = fullText;
|
|
4136
|
+
const chunks = splitToolCardText(fullText);
|
|
4137
|
+
this.tracer?.log("telegram", { action: "toolCard:render", sessionId: this.sessionId, chunks: chunks.length, total: snapshot.totalVisible, completed: snapshot.completedVisible, allComplete: snapshot.allComplete, msgId: this.msgId, entries: snapshot.specs.map((s) => ({ id: s.id, kind: s.kind, icon: s.icon, title: s.title })), html: fullText });
|
|
3539
4138
|
try {
|
|
4139
|
+
const firstChunk = chunks[0];
|
|
3540
4140
|
if (this.msgId) {
|
|
3541
4141
|
await this.sendQueue.enqueue(
|
|
3542
|
-
() => this.api.editMessageText(this.chatId, this.msgId,
|
|
3543
|
-
parse_mode: "HTML"
|
|
3544
|
-
})
|
|
4142
|
+
() => this.api.editMessageText(this.chatId, this.msgId, firstChunk, { parse_mode: "HTML" })
|
|
3545
4143
|
);
|
|
4144
|
+
this.tracer?.log("telegram", { action: "telegram:edit", sessionId: this.sessionId, msgId: this.msgId, html: firstChunk });
|
|
3546
4145
|
} else {
|
|
3547
4146
|
const result = await this.sendQueue.enqueue(
|
|
3548
|
-
() => this.api.sendMessage(this.chatId,
|
|
4147
|
+
() => this.api.sendMessage(this.chatId, firstChunk, {
|
|
3549
4148
|
message_thread_id: this.threadId,
|
|
3550
4149
|
parse_mode: "HTML",
|
|
3551
4150
|
disable_notification: true
|
|
3552
4151
|
})
|
|
3553
4152
|
);
|
|
3554
4153
|
if (result) this.msgId = result.message_id;
|
|
4154
|
+
this.tracer?.log("telegram", { action: "telegram:send", sessionId: this.sessionId, msgId: result?.message_id, html: firstChunk });
|
|
4155
|
+
}
|
|
4156
|
+
for (let i = 1; i < chunks.length; i++) {
|
|
4157
|
+
const overflowIdx = i - 1;
|
|
4158
|
+
if (overflowIdx < this.overflowMsgIds.length) {
|
|
4159
|
+
await this.sendQueue.enqueue(
|
|
4160
|
+
() => this.api.editMessageText(this.chatId, this.overflowMsgIds[overflowIdx], chunks[i], { parse_mode: "HTML" })
|
|
4161
|
+
);
|
|
4162
|
+
this.tracer?.log("telegram", { action: "telegram:edit:overflow", sessionId: this.sessionId, msgId: this.overflowMsgIds[overflowIdx] });
|
|
4163
|
+
} else {
|
|
4164
|
+
const result = await this.sendQueue.enqueue(
|
|
4165
|
+
() => this.api.sendMessage(this.chatId, chunks[i], {
|
|
4166
|
+
message_thread_id: this.threadId,
|
|
4167
|
+
parse_mode: "HTML",
|
|
4168
|
+
disable_notification: true
|
|
4169
|
+
})
|
|
4170
|
+
);
|
|
4171
|
+
if (result) this.overflowMsgIds.push(result.message_id);
|
|
4172
|
+
this.tracer?.log("telegram", { action: "telegram:send:overflow", sessionId: this.sessionId, msgId: result?.message_id });
|
|
4173
|
+
}
|
|
3555
4174
|
}
|
|
3556
4175
|
} catch (err) {
|
|
3557
4176
|
log10.warn({ err }, "[ToolCard] send/edit failed");
|
|
@@ -3559,59 +4178,140 @@ var ToolCard = class {
|
|
|
3559
4178
|
}
|
|
3560
4179
|
};
|
|
3561
4180
|
var ActivityTracker = class {
|
|
3562
|
-
constructor(api, chatId, threadId, sendQueue,
|
|
4181
|
+
constructor(api, chatId, threadId, sendQueue, outputMode = "medium", sessionId = "", tracer = null, tunnelService, sessionContext) {
|
|
3563
4182
|
this.api = api;
|
|
3564
4183
|
this.chatId = chatId;
|
|
3565
4184
|
this.threadId = threadId;
|
|
3566
4185
|
this.sendQueue = sendQueue;
|
|
3567
|
-
this.
|
|
3568
|
-
this.
|
|
4186
|
+
this._outputMode = outputMode;
|
|
4187
|
+
this.tracer = tracer;
|
|
4188
|
+
this.sessionId = sessionId;
|
|
4189
|
+
this.sessionContext = sessionContext;
|
|
4190
|
+
this.tunnelService = tunnelService;
|
|
4191
|
+
this.specBuilder = new DisplaySpecBuilder(tunnelService);
|
|
4192
|
+
this.toolStateMap = new ToolStateMap();
|
|
4193
|
+
this.thoughtBuffer = new ThoughtBuffer();
|
|
4194
|
+
this.thinking = new ThinkingIndicator(api, chatId, threadId, sendQueue, sessionId, tracer);
|
|
4195
|
+
this.toolCard = new ToolCard(api, chatId, threadId, sendQueue, sessionId, tracer);
|
|
3569
4196
|
}
|
|
3570
4197
|
isFirstEvent = true;
|
|
3571
4198
|
thinking;
|
|
3572
4199
|
toolCard;
|
|
4200
|
+
previousToolCard;
|
|
4201
|
+
toolStateMap;
|
|
4202
|
+
previousToolStateMap;
|
|
4203
|
+
specBuilder;
|
|
4204
|
+
thoughtBuffer;
|
|
4205
|
+
_outputMode;
|
|
4206
|
+
tracer;
|
|
4207
|
+
sessionId;
|
|
4208
|
+
sessionContext;
|
|
4209
|
+
tunnelService;
|
|
4210
|
+
setOutputMode(mode) {
|
|
4211
|
+
this._outputMode = mode;
|
|
4212
|
+
}
|
|
3573
4213
|
async onNewPrompt() {
|
|
4214
|
+
this.tracer?.log("telegram", { action: "tracker:newPrompt", sessionId: this.sessionId });
|
|
3574
4215
|
this.isFirstEvent = true;
|
|
3575
|
-
this.
|
|
4216
|
+
this.thoughtBuffer.reset();
|
|
4217
|
+
await this.thinking.dismiss();
|
|
3576
4218
|
this.thinking.reset();
|
|
4219
|
+
await this.toolCard.finalize();
|
|
4220
|
+
this.previousToolCard = void 0;
|
|
4221
|
+
this.previousToolStateMap = void 0;
|
|
4222
|
+
this.toolStateMap.clear();
|
|
4223
|
+
this.toolCard = new ToolCard(this.api, this.chatId, this.threadId, this.sendQueue, this.sessionId, this.tracer);
|
|
3577
4224
|
}
|
|
3578
|
-
async onThought() {
|
|
4225
|
+
async onThought(text) {
|
|
4226
|
+
this.tracer?.log("telegram", { action: "tracker:thought", sessionId: this.sessionId });
|
|
3579
4227
|
this.isFirstEvent = false;
|
|
4228
|
+
if (!this.thoughtBuffer.isSealed()) this.thoughtBuffer.append(text);
|
|
4229
|
+
await this.sealToolCardIfNeeded();
|
|
3580
4230
|
await this.thinking.show();
|
|
3581
4231
|
}
|
|
3582
4232
|
async onTextStart() {
|
|
4233
|
+
this.tracer?.log("telegram", { action: "tracker:textStart", sessionId: this.sessionId });
|
|
3583
4234
|
this.isFirstEvent = false;
|
|
3584
|
-
this.
|
|
4235
|
+
this.thoughtBuffer.seal();
|
|
4236
|
+
if (this._outputMode === "high" && this.tunnelService && this.sessionContext) {
|
|
4237
|
+
const thoughtText = this.thoughtBuffer.getText();
|
|
4238
|
+
if (thoughtText.trim().length > 0) {
|
|
4239
|
+
const id = this.tunnelService.getStore().storeOutput(
|
|
4240
|
+
this.sessionContext.id,
|
|
4241
|
+
"thinking",
|
|
4242
|
+
thoughtText
|
|
4243
|
+
);
|
|
4244
|
+
if (id !== null) {
|
|
4245
|
+
await this.thinking.finalizeWithViewerLink(this.tunnelService.outputUrl(id));
|
|
4246
|
+
} else {
|
|
4247
|
+
await this.thinking.dismiss();
|
|
4248
|
+
}
|
|
4249
|
+
} else {
|
|
4250
|
+
await this.thinking.dismiss();
|
|
4251
|
+
}
|
|
4252
|
+
} else {
|
|
4253
|
+
await this.thinking.dismiss();
|
|
4254
|
+
}
|
|
4255
|
+
await this.sealToolCardIfNeeded();
|
|
3585
4256
|
}
|
|
3586
4257
|
async onToolCall(meta, kind, rawInput) {
|
|
4258
|
+
this.tracer?.log("telegram", { action: "tracker:toolCall", sessionId: this.sessionId, meta, kind, rawInput });
|
|
3587
4259
|
this.isFirstEvent = false;
|
|
3588
|
-
this.thinking.dismiss();
|
|
4260
|
+
await this.thinking.dismiss();
|
|
3589
4261
|
this.thinking.reset();
|
|
3590
|
-
this.
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
4262
|
+
const entry = this.toolStateMap.upsert(meta, kind, rawInput);
|
|
4263
|
+
const spec = this.specBuilder.buildToolSpec(entry, this._outputMode, this.sessionContext);
|
|
4264
|
+
this.toolCard.updateFromSpec(spec);
|
|
4265
|
+
}
|
|
4266
|
+
async onToolUpdate(id, status, viewerLinks, viewerFilePath, content, rawInput, diffStats) {
|
|
4267
|
+
this.tracer?.log("telegram", { action: "tracker:toolUpdate", sessionId: this.sessionId, toolId: id, status, viewerLinks, viewerFilePath, hasPrevCard: !!this.previousToolCard });
|
|
4268
|
+
if (this.previousToolStateMap?.get(id)) {
|
|
4269
|
+
this.previousToolStateMap.merge(id, status, rawInput, content, viewerLinks, diffStats);
|
|
4270
|
+
const prevEntry = this.previousToolStateMap.get(id);
|
|
4271
|
+
if (prevEntry) {
|
|
4272
|
+
const prevSpec = this.specBuilder.buildToolSpec(prevEntry, this._outputMode, this.sessionContext);
|
|
4273
|
+
this.previousToolCard?.updateFromSpec(prevSpec);
|
|
4274
|
+
}
|
|
4275
|
+
}
|
|
4276
|
+
const existed = !!this.toolStateMap.get(id);
|
|
4277
|
+
const entry = this.toolStateMap.merge(id, status, rawInput, content, viewerLinks, diffStats);
|
|
4278
|
+
if (!existed || !entry) return;
|
|
4279
|
+
if (viewerLinks || entry.viewerLinks) {
|
|
4280
|
+
log10.debug({ toolId: id, status, hasIncomingLinks: !!viewerLinks, hasEntryLinks: !!entry.viewerLinks, entryLinks: entry.viewerLinks }, "toolUpdate: viewer links trace");
|
|
4281
|
+
}
|
|
4282
|
+
const spec = this.specBuilder.buildToolSpec(entry, this._outputMode, this.sessionContext);
|
|
4283
|
+
this.toolCard.updateFromSpec(spec);
|
|
3594
4284
|
}
|
|
3595
4285
|
async onPlan(entries) {
|
|
4286
|
+
this.tracer?.log("telegram", { action: "tracker:plan", sessionId: this.sessionId, entries });
|
|
3596
4287
|
this.isFirstEvent = false;
|
|
3597
|
-
this.thinking.dismiss();
|
|
4288
|
+
await this.thinking.dismiss();
|
|
3598
4289
|
this.toolCard.updatePlan(entries);
|
|
3599
4290
|
}
|
|
3600
|
-
|
|
3601
|
-
|
|
4291
|
+
/** @deprecated Usage is now sent as a separate message by the adapter */
|
|
4292
|
+
async sendUsage(_usage) {
|
|
3602
4293
|
}
|
|
3603
|
-
|
|
4294
|
+
getToolCardMsgId() {
|
|
3604
4295
|
return this.toolCard.getMsgId();
|
|
3605
4296
|
}
|
|
3606
4297
|
async cleanup() {
|
|
3607
|
-
this.thinking.dismiss();
|
|
4298
|
+
await this.thinking.dismiss();
|
|
3608
4299
|
await this.toolCard.finalize();
|
|
3609
4300
|
this.toolCard.destroy();
|
|
3610
4301
|
}
|
|
3611
4302
|
destroy() {
|
|
3612
|
-
this.thinking.dismiss();
|
|
4303
|
+
void this.thinking.dismiss();
|
|
3613
4304
|
this.toolCard.destroy();
|
|
3614
4305
|
}
|
|
4306
|
+
async sealToolCardIfNeeded() {
|
|
4307
|
+
if (!this.toolCard.hasContent()) return;
|
|
4308
|
+
this.tracer?.log("telegram", { action: "tracker:seal", sessionId: this.sessionId });
|
|
4309
|
+
await this.toolCard.finalize();
|
|
4310
|
+
this.previousToolCard = this.toolCard;
|
|
4311
|
+
this.previousToolStateMap = this.toolStateMap;
|
|
4312
|
+
this.toolStateMap = new ToolStateMap();
|
|
4313
|
+
this.toolCard = new ToolCard(this.api, this.chatId, this.threadId, this.sendQueue, this.sessionId, this.tracer);
|
|
4314
|
+
}
|
|
3615
4315
|
};
|
|
3616
4316
|
|
|
3617
4317
|
// src/core/adapter-primitives/primitives/send-queue.ts
|
|
@@ -3872,12 +4572,13 @@ function setupActionCallbacks(bot, core, chatId, getAssistantSessionId) {
|
|
|
3872
4572
|
// src/plugins/telegram/streaming.ts
|
|
3873
4573
|
var FLUSH_INTERVAL = 5e3;
|
|
3874
4574
|
var MessageDraft = class {
|
|
3875
|
-
constructor(bot, chatId, threadId, sendQueue, sessionId) {
|
|
4575
|
+
constructor(bot, chatId, threadId, sendQueue, sessionId, tracer = null) {
|
|
3876
4576
|
this.bot = bot;
|
|
3877
4577
|
this.chatId = chatId;
|
|
3878
4578
|
this.threadId = threadId;
|
|
3879
4579
|
this.sendQueue = sendQueue;
|
|
3880
4580
|
this.sessionId = sessionId;
|
|
4581
|
+
this.tracer = tracer;
|
|
3881
4582
|
}
|
|
3882
4583
|
buffer = "";
|
|
3883
4584
|
messageId;
|
|
@@ -3886,6 +4587,7 @@ var MessageDraft = class {
|
|
|
3886
4587
|
flushPromise = Promise.resolve();
|
|
3887
4588
|
lastSentBuffer = "";
|
|
3888
4589
|
displayTruncated = false;
|
|
4590
|
+
tracer;
|
|
3889
4591
|
append(text) {
|
|
3890
4592
|
if (!text) return;
|
|
3891
4593
|
this.buffer += text;
|
|
@@ -3930,6 +4632,7 @@ var MessageDraft = class {
|
|
|
3930
4632
|
);
|
|
3931
4633
|
if (result) {
|
|
3932
4634
|
this.messageId = result.message_id;
|
|
4635
|
+
this.tracer?.log("telegram", { action: "draft:send", sessionId: this.sessionId, msgId: result.message_id, textLen: snapshot.length, truncated, text: snapshot });
|
|
3933
4636
|
if (!truncated) {
|
|
3934
4637
|
this.lastSentBuffer = snapshot;
|
|
3935
4638
|
this.displayTruncated = false;
|
|
@@ -3950,6 +4653,7 @@ var MessageDraft = class {
|
|
|
3950
4653
|
{ type: "text", key: this.sessionId }
|
|
3951
4654
|
);
|
|
3952
4655
|
if (result !== void 0) {
|
|
4656
|
+
this.tracer?.log("telegram", { action: "draft:edit", sessionId: this.sessionId, msgId: this.messageId, textLen: snapshot.length, truncated, text: snapshot });
|
|
3953
4657
|
if (!truncated) {
|
|
3954
4658
|
this.lastSentBuffer = snapshot;
|
|
3955
4659
|
this.displayTruncated = false;
|
|
@@ -3962,6 +4666,7 @@ var MessageDraft = class {
|
|
|
3962
4666
|
}
|
|
3963
4667
|
}
|
|
3964
4668
|
async finalize() {
|
|
4669
|
+
this.tracer?.log("telegram", { action: "draft:finalize", sessionId: this.sessionId, bufferLen: this.buffer.length, msgId: this.messageId });
|
|
3965
4670
|
if (this.flushTimer) {
|
|
3966
4671
|
clearTimeout(this.flushTimer);
|
|
3967
4672
|
this.flushTimer = void 0;
|
|
@@ -3981,6 +4686,7 @@ var MessageDraft = class {
|
|
|
3981
4686
|
}),
|
|
3982
4687
|
{ type: "other" }
|
|
3983
4688
|
);
|
|
4689
|
+
this.tracer?.log("telegram", { action: "draft:finalize:edit", sessionId: this.sessionId, msgId: this.messageId });
|
|
3984
4690
|
} else {
|
|
3985
4691
|
const msg = await this.sendQueue.enqueue(
|
|
3986
4692
|
() => this.bot.api.sendMessage(this.chatId, fullHtml, {
|
|
@@ -3991,6 +4697,7 @@ var MessageDraft = class {
|
|
|
3991
4697
|
{ type: "other" }
|
|
3992
4698
|
);
|
|
3993
4699
|
if (msg) this.messageId = msg.message_id;
|
|
4700
|
+
this.tracer?.log("telegram", { action: "draft:finalize:send", sessionId: this.sessionId, msgId: msg?.message_id });
|
|
3994
4701
|
}
|
|
3995
4702
|
return this.messageId;
|
|
3996
4703
|
} catch {
|
|
@@ -4026,6 +4733,7 @@ var MessageDraft = class {
|
|
|
4026
4733
|
chunkPromises.push(promise);
|
|
4027
4734
|
}
|
|
4028
4735
|
await Promise.all(chunkPromises);
|
|
4736
|
+
this.tracer?.log("telegram", { action: "draft:finalize:split", sessionId: this.sessionId, chunks: mdChunks.length });
|
|
4029
4737
|
return this.messageId;
|
|
4030
4738
|
}
|
|
4031
4739
|
getMessageId() {
|
|
@@ -4060,7 +4768,8 @@ var DraftManager = class {
|
|
|
4060
4768
|
}
|
|
4061
4769
|
drafts = /* @__PURE__ */ new Map();
|
|
4062
4770
|
textBuffers = /* @__PURE__ */ new Map();
|
|
4063
|
-
|
|
4771
|
+
finalizedDrafts = /* @__PURE__ */ new Map();
|
|
4772
|
+
getOrCreate(sessionId, threadId, tracer = null) {
|
|
4064
4773
|
let draft = this.drafts.get(sessionId);
|
|
4065
4774
|
if (!draft) {
|
|
4066
4775
|
draft = new MessageDraft(
|
|
@@ -4068,7 +4777,8 @@ var DraftManager = class {
|
|
|
4068
4777
|
this.chatId,
|
|
4069
4778
|
threadId,
|
|
4070
4779
|
this.sendQueue,
|
|
4071
|
-
sessionId
|
|
4780
|
+
sessionId,
|
|
4781
|
+
tracer
|
|
4072
4782
|
);
|
|
4073
4783
|
this.drafts.set(sessionId, draft);
|
|
4074
4784
|
}
|
|
@@ -4095,6 +4805,9 @@ var DraftManager = class {
|
|
|
4095
4805
|
if (!draft) return;
|
|
4096
4806
|
this.drafts.delete(sessionId);
|
|
4097
4807
|
const finalMsgId = await draft.finalize();
|
|
4808
|
+
if (finalMsgId) {
|
|
4809
|
+
this.finalizedDrafts.set(sessionId, { messageId: finalMsgId, draft });
|
|
4810
|
+
}
|
|
4098
4811
|
if (assistantSessionId && sessionId === assistantSessionId) {
|
|
4099
4812
|
const fullText = this.textBuffers.get(sessionId);
|
|
4100
4813
|
this.textBuffers.delete(sessionId);
|
|
@@ -4117,9 +4830,25 @@ var DraftManager = class {
|
|
|
4117
4830
|
this.textBuffers.delete(sessionId);
|
|
4118
4831
|
}
|
|
4119
4832
|
}
|
|
4833
|
+
/**
|
|
4834
|
+
* Strip a regex pattern from the active or finalized draft for a session.
|
|
4835
|
+
* Used by tts_strip to remove [TTS]...[/TTS] blocks after TTS audio is sent.
|
|
4836
|
+
*/
|
|
4837
|
+
async stripPattern(sessionId, pattern) {
|
|
4838
|
+
const draft = this.drafts.get(sessionId);
|
|
4839
|
+
if (draft) {
|
|
4840
|
+
await draft.stripPattern(pattern);
|
|
4841
|
+
return;
|
|
4842
|
+
}
|
|
4843
|
+
const finalized = this.finalizedDrafts.get(sessionId);
|
|
4844
|
+
if (finalized) {
|
|
4845
|
+
await finalized.draft.stripPattern(pattern);
|
|
4846
|
+
}
|
|
4847
|
+
}
|
|
4120
4848
|
cleanup(sessionId) {
|
|
4121
4849
|
this.drafts.delete(sessionId);
|
|
4122
4850
|
this.textBuffers.delete(sessionId);
|
|
4851
|
+
this.finalizedDrafts.delete(sessionId);
|
|
4123
4852
|
}
|
|
4124
4853
|
};
|
|
4125
4854
|
|
|
@@ -4218,6 +4947,231 @@ var SkillCommandManager = class {
|
|
|
4218
4947
|
}
|
|
4219
4948
|
};
|
|
4220
4949
|
|
|
4950
|
+
// src/core/adapter-primitives/messaging-adapter.ts
|
|
4951
|
+
var HIDDEN_ON_LOW = /* @__PURE__ */ new Set(["thought", "usage"]);
|
|
4952
|
+
var MessagingAdapter = class {
|
|
4953
|
+
constructor(context, adapterConfig) {
|
|
4954
|
+
this.context = context;
|
|
4955
|
+
this.adapterConfig = adapterConfig;
|
|
4956
|
+
}
|
|
4957
|
+
// === Message dispatch flow ===
|
|
4958
|
+
async sendMessage(sessionId, content) {
|
|
4959
|
+
const verbosity = this.getVerbosity();
|
|
4960
|
+
if (!this.shouldDisplay(content, verbosity)) return;
|
|
4961
|
+
await this.dispatchMessage(sessionId, content, verbosity);
|
|
4962
|
+
}
|
|
4963
|
+
async dispatchMessage(sessionId, content, verbosity) {
|
|
4964
|
+
switch (content.type) {
|
|
4965
|
+
case "text":
|
|
4966
|
+
return this.handleText(sessionId, content);
|
|
4967
|
+
case "thought":
|
|
4968
|
+
return this.handleThought(sessionId, content, verbosity);
|
|
4969
|
+
case "tool_call":
|
|
4970
|
+
return this.handleToolCall(sessionId, content, verbosity);
|
|
4971
|
+
case "tool_update":
|
|
4972
|
+
return this.handleToolUpdate(sessionId, content, verbosity);
|
|
4973
|
+
case "plan":
|
|
4974
|
+
return this.handlePlan(sessionId, content, verbosity);
|
|
4975
|
+
case "usage":
|
|
4976
|
+
return this.handleUsage(sessionId, content, verbosity);
|
|
4977
|
+
case "error":
|
|
4978
|
+
return this.handleError(sessionId, content);
|
|
4979
|
+
case "attachment":
|
|
4980
|
+
return this.handleAttachment(sessionId, content);
|
|
4981
|
+
case "system_message":
|
|
4982
|
+
return this.handleSystem(sessionId, content);
|
|
4983
|
+
case "session_end":
|
|
4984
|
+
return this.handleSessionEnd(sessionId, content);
|
|
4985
|
+
case "mode_change":
|
|
4986
|
+
return this.handleModeChange(sessionId, content);
|
|
4987
|
+
case "config_update":
|
|
4988
|
+
return this.handleConfigUpdate(sessionId, content);
|
|
4989
|
+
case "model_update":
|
|
4990
|
+
return this.handleModelUpdate(sessionId, content);
|
|
4991
|
+
case "user_replay":
|
|
4992
|
+
return this.handleUserReplay(sessionId, content);
|
|
4993
|
+
case "resource":
|
|
4994
|
+
return this.handleResource(sessionId, content);
|
|
4995
|
+
case "resource_link":
|
|
4996
|
+
return this.handleResourceLink(sessionId, content);
|
|
4997
|
+
}
|
|
4998
|
+
}
|
|
4999
|
+
// === Default handlers — all protected, all overridable ===
|
|
5000
|
+
async handleText(_sessionId, _content) {
|
|
5001
|
+
}
|
|
5002
|
+
async handleThought(_sessionId, _content, _verbosity) {
|
|
5003
|
+
}
|
|
5004
|
+
async handleToolCall(_sessionId, _content, _verbosity) {
|
|
5005
|
+
}
|
|
5006
|
+
async handleToolUpdate(_sessionId, _content, _verbosity) {
|
|
5007
|
+
}
|
|
5008
|
+
async handlePlan(_sessionId, _content, _verbosity) {
|
|
5009
|
+
}
|
|
5010
|
+
async handleUsage(_sessionId, _content, _verbosity) {
|
|
5011
|
+
}
|
|
5012
|
+
async handleError(_sessionId, _content) {
|
|
5013
|
+
}
|
|
5014
|
+
async handleAttachment(_sessionId, _content) {
|
|
5015
|
+
}
|
|
5016
|
+
async handleSystem(_sessionId, _content) {
|
|
5017
|
+
}
|
|
5018
|
+
async handleSessionEnd(_sessionId, _content) {
|
|
5019
|
+
}
|
|
5020
|
+
async handleModeChange(_sessionId, _content) {
|
|
5021
|
+
}
|
|
5022
|
+
async handleConfigUpdate(_sessionId, _content) {
|
|
5023
|
+
}
|
|
5024
|
+
async handleModelUpdate(_sessionId, _content) {
|
|
5025
|
+
}
|
|
5026
|
+
async handleUserReplay(_sessionId, _content) {
|
|
5027
|
+
}
|
|
5028
|
+
async handleResource(_sessionId, _content) {
|
|
5029
|
+
}
|
|
5030
|
+
async handleResourceLink(_sessionId, _content) {
|
|
5031
|
+
}
|
|
5032
|
+
// === Helpers ===
|
|
5033
|
+
getVerbosity() {
|
|
5034
|
+
const config = this.context.configManager.get();
|
|
5035
|
+
const channelConfig = config.channels;
|
|
5036
|
+
const v = channelConfig?.[this.name]?.displayVerbosity ?? this.adapterConfig.displayVerbosity;
|
|
5037
|
+
if (v === "low" || v === "high") return v;
|
|
5038
|
+
return "medium";
|
|
5039
|
+
}
|
|
5040
|
+
shouldDisplay(content, verbosity) {
|
|
5041
|
+
if (verbosity === "low" && HIDDEN_ON_LOW.has(content.type)) return false;
|
|
5042
|
+
if (content.type === "tool_call") {
|
|
5043
|
+
const meta = content.metadata ?? {};
|
|
5044
|
+
const toolName = meta.name ?? content.text ?? "";
|
|
5045
|
+
const toolKind = String(meta.kind ?? "other");
|
|
5046
|
+
const noiseAction = evaluateNoise(toolName, toolKind, meta.rawInput);
|
|
5047
|
+
if (noiseAction === "hide" && verbosity !== "high") return false;
|
|
5048
|
+
if (noiseAction === "collapse" && verbosity === "low") return false;
|
|
5049
|
+
}
|
|
5050
|
+
return true;
|
|
5051
|
+
}
|
|
5052
|
+
};
|
|
5053
|
+
|
|
5054
|
+
// src/core/adapter-primitives/rendering/renderer.ts
|
|
5055
|
+
var BaseRenderer = class {
|
|
5056
|
+
renderText(content) {
|
|
5057
|
+
return { body: content.text, format: "plain" };
|
|
5058
|
+
}
|
|
5059
|
+
renderToolCall(content, verbosity) {
|
|
5060
|
+
const meta = content.metadata ?? {};
|
|
5061
|
+
const name = meta.name ?? content.text ?? "Tool";
|
|
5062
|
+
const icon = resolveToolIcon(meta);
|
|
5063
|
+
const label = verbosity === "low" ? formatToolTitle(
|
|
5064
|
+
name,
|
|
5065
|
+
meta.rawInput,
|
|
5066
|
+
meta.displayTitle
|
|
5067
|
+
) : formatToolSummary(
|
|
5068
|
+
name,
|
|
5069
|
+
meta.rawInput,
|
|
5070
|
+
meta.displaySummary
|
|
5071
|
+
);
|
|
5072
|
+
return { body: `${icon} ${label}`, format: "plain" };
|
|
5073
|
+
}
|
|
5074
|
+
renderToolUpdate(content, verbosity) {
|
|
5075
|
+
const meta = content.metadata ?? {};
|
|
5076
|
+
const name = meta.name ?? content.text ?? "Tool";
|
|
5077
|
+
const icon = resolveToolIcon(meta);
|
|
5078
|
+
const label = verbosity === "low" ? formatToolTitle(
|
|
5079
|
+
name,
|
|
5080
|
+
meta.rawInput,
|
|
5081
|
+
meta.displayTitle
|
|
5082
|
+
) : formatToolSummary(
|
|
5083
|
+
name,
|
|
5084
|
+
meta.rawInput,
|
|
5085
|
+
meta.displaySummary
|
|
5086
|
+
);
|
|
5087
|
+
return { body: `${icon} ${label}`, format: "plain" };
|
|
5088
|
+
}
|
|
5089
|
+
renderPlan(content) {
|
|
5090
|
+
const entries = content.metadata?.entries ?? [];
|
|
5091
|
+
const lines = entries.map((e, i) => {
|
|
5092
|
+
const icon = e.status === "completed" ? "\u2705" : e.status === "in_progress" ? "\u{1F504}" : "\u2B1C";
|
|
5093
|
+
return `${icon} ${i + 1}. ${e.content}`;
|
|
5094
|
+
});
|
|
5095
|
+
return { body: `\u{1F4CB} Plan
|
|
5096
|
+
${lines.join("\n")}`, format: "plain" };
|
|
5097
|
+
}
|
|
5098
|
+
renderUsage(content, verbosity) {
|
|
5099
|
+
const meta = content.metadata;
|
|
5100
|
+
if (!meta?.tokensUsed)
|
|
5101
|
+
return { body: "\u{1F4CA} Usage data unavailable", format: "plain" };
|
|
5102
|
+
const costStr = meta.cost != null ? ` \xB7 $${meta.cost.toFixed(2)}` : "";
|
|
5103
|
+
if (verbosity === "medium") {
|
|
5104
|
+
return {
|
|
5105
|
+
body: `\u{1F4CA} ${formatTokens(meta.tokensUsed)} tokens${costStr}`,
|
|
5106
|
+
format: "plain"
|
|
5107
|
+
};
|
|
5108
|
+
}
|
|
5109
|
+
if (!meta.contextSize)
|
|
5110
|
+
return {
|
|
5111
|
+
body: `\u{1F4CA} ${formatTokens(meta.tokensUsed)} tokens`,
|
|
5112
|
+
format: "plain"
|
|
5113
|
+
};
|
|
5114
|
+
const ratio = meta.tokensUsed / meta.contextSize;
|
|
5115
|
+
const pct = Math.round(ratio * 100);
|
|
5116
|
+
const bar = progressBar(ratio);
|
|
5117
|
+
let text = `\u{1F4CA} ${formatTokens(meta.tokensUsed)} / ${formatTokens(meta.contextSize)} tokens
|
|
5118
|
+
${bar} ${pct}%`;
|
|
5119
|
+
if (meta.cost != null) text += `
|
|
5120
|
+
\u{1F4B0} $${meta.cost.toFixed(2)}`;
|
|
5121
|
+
return { body: text, format: "plain" };
|
|
5122
|
+
}
|
|
5123
|
+
renderPermission(request) {
|
|
5124
|
+
return {
|
|
5125
|
+
body: request.description,
|
|
5126
|
+
format: "plain",
|
|
5127
|
+
actions: request.options.map((o) => ({
|
|
5128
|
+
id: o.id,
|
|
5129
|
+
label: o.label,
|
|
5130
|
+
isAllow: o.isAllow
|
|
5131
|
+
}))
|
|
5132
|
+
};
|
|
5133
|
+
}
|
|
5134
|
+
renderError(content) {
|
|
5135
|
+
return { body: `\u274C Error: ${content.text}`, format: "plain" };
|
|
5136
|
+
}
|
|
5137
|
+
renderNotification(notification) {
|
|
5138
|
+
const emoji = {
|
|
5139
|
+
completed: "\u2705",
|
|
5140
|
+
error: "\u274C",
|
|
5141
|
+
permission: "\u{1F510}",
|
|
5142
|
+
input_required: "\u{1F4AC}",
|
|
5143
|
+
budget_warning: "\u26A0\uFE0F"
|
|
5144
|
+
};
|
|
5145
|
+
return {
|
|
5146
|
+
body: `${emoji[notification.type] || "\u2139\uFE0F"} ${notification.sessionName || "Session"}
|
|
5147
|
+
${notification.summary}`,
|
|
5148
|
+
format: "plain"
|
|
5149
|
+
};
|
|
5150
|
+
}
|
|
5151
|
+
renderSystemMessage(content) {
|
|
5152
|
+
return { body: content.text, format: "plain" };
|
|
5153
|
+
}
|
|
5154
|
+
renderModeChange(content) {
|
|
5155
|
+
const modeId = content.metadata?.modeId ?? "";
|
|
5156
|
+
return { body: `\u{1F504} Mode: ${modeId}`, format: "plain" };
|
|
5157
|
+
}
|
|
5158
|
+
renderConfigUpdate() {
|
|
5159
|
+
return { body: "\u2699\uFE0F Config updated", format: "plain" };
|
|
5160
|
+
}
|
|
5161
|
+
renderModelUpdate(content) {
|
|
5162
|
+
const modelId = content.metadata?.modelId ?? "";
|
|
5163
|
+
return { body: `\u{1F916} Model: ${modelId}`, format: "plain" };
|
|
5164
|
+
}
|
|
5165
|
+
renderResource(content) {
|
|
5166
|
+
const uri = content.metadata?.uri ?? "";
|
|
5167
|
+
return { body: `\u{1F4C4} Resource: ${content.text} (${uri})`, format: "plain" };
|
|
5168
|
+
}
|
|
5169
|
+
renderResourceLink(content) {
|
|
5170
|
+
const uri = content.metadata?.uri ?? "";
|
|
5171
|
+
return { body: `\u{1F517} ${content.text}: ${uri}`, format: "plain" };
|
|
5172
|
+
}
|
|
5173
|
+
};
|
|
5174
|
+
|
|
4221
5175
|
// src/plugins/telegram/renderer.ts
|
|
4222
5176
|
var TelegramRenderer = class extends BaseRenderer {
|
|
4223
5177
|
renderToolCall(content, verbosity) {
|
|
@@ -4286,6 +5240,28 @@ var TelegramRenderer = class extends BaseRenderer {
|
|
|
4286
5240
|
}
|
|
4287
5241
|
};
|
|
4288
5242
|
|
|
5243
|
+
// src/core/adapter-primitives/output-mode-resolver.ts
|
|
5244
|
+
var VALID_MODES = /* @__PURE__ */ new Set(["low", "medium", "high"]);
|
|
5245
|
+
function toOutputMode(v) {
|
|
5246
|
+
return typeof v === "string" && VALID_MODES.has(v) ? v : void 0;
|
|
5247
|
+
}
|
|
5248
|
+
var OutputModeResolver = class {
|
|
5249
|
+
resolve(configManager, adapterName, sessionId, sessionManager) {
|
|
5250
|
+
const config = configManager.get();
|
|
5251
|
+
let mode = toOutputMode(config.outputMode) ?? "medium";
|
|
5252
|
+
const channels = config.channels;
|
|
5253
|
+
const channelCfg = channels?.[adapterName];
|
|
5254
|
+
const adapterMode = toOutputMode(channelCfg?.outputMode);
|
|
5255
|
+
if (adapterMode) mode = adapterMode;
|
|
5256
|
+
if (sessionId && sessionManager) {
|
|
5257
|
+
const session = sessionManager.getSession(sessionId);
|
|
5258
|
+
const sessionMode = session?.record?.outputMode;
|
|
5259
|
+
if (sessionMode) mode = sessionMode;
|
|
5260
|
+
}
|
|
5261
|
+
return mode;
|
|
5262
|
+
}
|
|
5263
|
+
};
|
|
5264
|
+
|
|
4289
5265
|
// src/plugins/telegram/adapter.ts
|
|
4290
5266
|
var log12 = createChildLogger({ module: "telegram" });
|
|
4291
5267
|
function patchedFetch(input, init) {
|
|
@@ -4322,6 +5298,7 @@ var TelegramAdapter = class extends MessagingAdapter {
|
|
|
4322
5298
|
assistantTopicId;
|
|
4323
5299
|
sendQueue = new SendQueue({ minInterval: 3e3 });
|
|
4324
5300
|
_sessionThreadIds = /* @__PURE__ */ new Map();
|
|
5301
|
+
outputModeResolver = new OutputModeResolver();
|
|
4325
5302
|
// Extracted managers
|
|
4326
5303
|
draftManager;
|
|
4327
5304
|
skillManager;
|
|
@@ -4336,17 +5313,29 @@ var TelegramAdapter = class extends MessagingAdapter {
|
|
|
4336
5313
|
}
|
|
4337
5314
|
return threadId;
|
|
4338
5315
|
}
|
|
4339
|
-
getOrCreateTracker(sessionId, threadId,
|
|
5316
|
+
getOrCreateTracker(sessionId, threadId, outputMode = "medium") {
|
|
4340
5317
|
let tracker = this.sessionTrackers.get(sessionId);
|
|
4341
5318
|
if (!tracker) {
|
|
5319
|
+
const tunnelService = this.core.lifecycleManager?.serviceRegistry?.get("tunnel");
|
|
5320
|
+
const session = this.core.sessionManager.getSession(sessionId);
|
|
5321
|
+
const sessionContext = session ? {
|
|
5322
|
+
id: sessionId,
|
|
5323
|
+
workingDirectory: session.workingDirectory
|
|
5324
|
+
} : void 0;
|
|
4342
5325
|
tracker = new ActivityTracker(
|
|
4343
5326
|
this.bot.api,
|
|
4344
5327
|
this.telegramConfig.chatId,
|
|
4345
5328
|
threadId,
|
|
4346
5329
|
this.sendQueue,
|
|
4347
|
-
|
|
5330
|
+
outputMode,
|
|
5331
|
+
sessionId,
|
|
5332
|
+
this.getTracer(sessionId),
|
|
5333
|
+
tunnelService,
|
|
5334
|
+
sessionContext
|
|
4348
5335
|
);
|
|
4349
5336
|
this.sessionTrackers.set(sessionId, tracker);
|
|
5337
|
+
} else {
|
|
5338
|
+
tracker.setOutputMode(outputMode);
|
|
4350
5339
|
}
|
|
4351
5340
|
return tracker;
|
|
4352
5341
|
}
|
|
@@ -4600,7 +5589,7 @@ var TelegramAdapter = class extends MessagingAdapter {
|
|
|
4600
5589
|
});
|
|
4601
5590
|
return;
|
|
4602
5591
|
}
|
|
4603
|
-
const { getAgentCapabilities } = await import("./agent-registry-
|
|
5592
|
+
const { getAgentCapabilities } = await import("./agent-registry-YOGP656W.js");
|
|
4604
5593
|
const caps = getAgentCapabilities(agentName);
|
|
4605
5594
|
if (!caps.supportsResume || !caps.resumeCommand) {
|
|
4606
5595
|
await ctx.reply("This agent does not support session transfer.", {
|
|
@@ -4681,6 +5670,11 @@ var TelegramAdapter = class extends MessagingAdapter {
|
|
|
4681
5670
|
}
|
|
4682
5671
|
}
|
|
4683
5672
|
async stop() {
|
|
5673
|
+
for (const tracker of this.sessionTrackers.values()) {
|
|
5674
|
+
tracker.destroy();
|
|
5675
|
+
}
|
|
5676
|
+
this.sessionTrackers.clear();
|
|
5677
|
+
this.sendQueue.clear();
|
|
4684
5678
|
if (this.assistantSession) {
|
|
4685
5679
|
await this.assistantSession.destroy();
|
|
4686
5680
|
}
|
|
@@ -4821,8 +5815,10 @@ ${lines.join("\n")}`;
|
|
|
4821
5815
|
"telegram",
|
|
4822
5816
|
String(threadId)
|
|
4823
5817
|
)?.id;
|
|
4824
|
-
if (sessionId)
|
|
5818
|
+
if (sessionId) {
|
|
5819
|
+
this.getTracer(sessionId)?.log("telegram", { action: "incoming:message", sessionId, userId: String(ctx.from?.id), text: ctx.message?.text });
|
|
4825
5820
|
await this.draftManager.finalize(sessionId, this.assistantSession?.id);
|
|
5821
|
+
}
|
|
4826
5822
|
if (sessionId) {
|
|
4827
5823
|
const tracker = this.sessionTrackers.get(sessionId);
|
|
4828
5824
|
if (tracker) await tracker.onNewPrompt();
|
|
@@ -4905,6 +5901,18 @@ ${lines.join("\n")}`;
|
|
|
4905
5901
|
});
|
|
4906
5902
|
}
|
|
4907
5903
|
// --- MessagingAdapter overrides ---
|
|
5904
|
+
/**
|
|
5905
|
+
* Per-session serial dispatch queues.
|
|
5906
|
+
* SessionBridge fires sendMessage() as fire-and-forget, so multiple events
|
|
5907
|
+
* (tool_call, tool_update, text) can arrive concurrently. Without serialization,
|
|
5908
|
+
* fast handlers (tool_update) overtake slow ones (tool_call with draftManager.finalize),
|
|
5909
|
+
* causing out-of-order processing where a tool's completion update is processed before
|
|
5910
|
+
* its creation event. This queue ensures events are processed in the order they arrive.
|
|
5911
|
+
*/
|
|
5912
|
+
_dispatchQueues = /* @__PURE__ */ new Map();
|
|
5913
|
+
getTracer(sessionId) {
|
|
5914
|
+
return this.core.sessionManager.getSession(sessionId)?.agentInstance?.debugTracer ?? null;
|
|
5915
|
+
}
|
|
4908
5916
|
async sendMessage(sessionId, content) {
|
|
4909
5917
|
if (this.assistantInitializing && sessionId === this.assistantSession?.id)
|
|
4910
5918
|
return;
|
|
@@ -4919,33 +5927,61 @@ ${lines.join("\n")}`;
|
|
|
4919
5927
|
);
|
|
4920
5928
|
return;
|
|
4921
5929
|
}
|
|
4922
|
-
this.
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
5930
|
+
const prev = this._dispatchQueues.get(sessionId) ?? Promise.resolve();
|
|
5931
|
+
const next = prev.then(async () => {
|
|
5932
|
+
this.getTracer(sessionId)?.log("telegram", { action: "dispatch:enter", sessionId, message: content });
|
|
5933
|
+
this._sessionThreadIds.set(sessionId, threadId);
|
|
5934
|
+
try {
|
|
5935
|
+
await super.sendMessage(sessionId, content);
|
|
5936
|
+
} finally {
|
|
5937
|
+
this._sessionThreadIds.delete(sessionId);
|
|
5938
|
+
}
|
|
5939
|
+
}).catch((err) => {
|
|
5940
|
+
log12.warn({ err, sessionId }, "Dispatch queue error");
|
|
5941
|
+
});
|
|
5942
|
+
this._dispatchQueues.set(sessionId, next);
|
|
5943
|
+
await next;
|
|
4928
5944
|
}
|
|
4929
|
-
async handleThought(sessionId,
|
|
5945
|
+
async handleThought(sessionId, content, _verbosity) {
|
|
5946
|
+
this.getTracer(sessionId)?.log("telegram", { action: "handle:thought", sessionId, text: content.text });
|
|
4930
5947
|
const threadId = this.getThreadId(sessionId);
|
|
4931
|
-
const
|
|
4932
|
-
|
|
5948
|
+
const mode = this.outputModeResolver.resolve(
|
|
5949
|
+
this.context.configManager,
|
|
5950
|
+
this.name,
|
|
5951
|
+
sessionId,
|
|
5952
|
+
this.core.sessionManager
|
|
5953
|
+
);
|
|
5954
|
+
const tracker = this.getOrCreateTracker(sessionId, threadId, mode);
|
|
5955
|
+
await tracker.onThought(content.text);
|
|
4933
5956
|
}
|
|
4934
5957
|
async handleText(sessionId, content) {
|
|
5958
|
+
this.getTracer(sessionId)?.log("telegram", { action: "handle:text", sessionId, text: content.text });
|
|
4935
5959
|
const threadId = this.getThreadId(sessionId);
|
|
4936
5960
|
if (!this.draftManager.hasDraft(sessionId)) {
|
|
4937
|
-
const
|
|
4938
|
-
|
|
4939
|
-
|
|
5961
|
+
const mode = this.outputModeResolver.resolve(
|
|
5962
|
+
this.context.configManager,
|
|
5963
|
+
this.name,
|
|
5964
|
+
sessionId,
|
|
5965
|
+
this.core.sessionManager
|
|
5966
|
+
);
|
|
5967
|
+
const tracker = this.getOrCreateTracker(sessionId, threadId, mode);
|
|
5968
|
+
await tracker.onTextStart();
|
|
4940
5969
|
}
|
|
4941
|
-
const draft = this.draftManager.getOrCreate(sessionId, threadId);
|
|
5970
|
+
const draft = this.draftManager.getOrCreate(sessionId, threadId, this.getTracer(sessionId));
|
|
4942
5971
|
draft.append(content.text);
|
|
4943
5972
|
this.draftManager.appendText(sessionId, content.text);
|
|
4944
5973
|
}
|
|
4945
|
-
async handleToolCall(sessionId, content,
|
|
5974
|
+
async handleToolCall(sessionId, content, _verbosity) {
|
|
4946
5975
|
const threadId = this.getThreadId(sessionId);
|
|
4947
5976
|
const meta = content.metadata ?? {};
|
|
4948
|
-
|
|
5977
|
+
this.getTracer(sessionId)?.log("telegram", { action: "handle:toolCall", sessionId, toolId: meta.id, toolName: meta.name, kind: meta.kind, status: meta.status, displaySummary: meta.displaySummary, rawInput: meta.rawInput });
|
|
5978
|
+
const mode = this.outputModeResolver.resolve(
|
|
5979
|
+
this.context.configManager,
|
|
5980
|
+
this.name,
|
|
5981
|
+
sessionId,
|
|
5982
|
+
this.core.sessionManager
|
|
5983
|
+
);
|
|
5984
|
+
const tracker = this.getOrCreateTracker(sessionId, threadId, mode);
|
|
4949
5985
|
await this.draftManager.finalize(sessionId, this.assistantSession?.id);
|
|
4950
5986
|
await tracker.onToolCall(
|
|
4951
5987
|
{
|
|
@@ -4965,22 +6001,39 @@ ${lines.join("\n")}`;
|
|
|
4965
6001
|
meta.rawInput
|
|
4966
6002
|
);
|
|
4967
6003
|
}
|
|
4968
|
-
async handleToolUpdate(sessionId, content,
|
|
6004
|
+
async handleToolUpdate(sessionId, content, _verbosity) {
|
|
4969
6005
|
const threadId = this.getThreadId(sessionId);
|
|
4970
6006
|
const meta = content.metadata ?? {};
|
|
4971
|
-
|
|
6007
|
+
this.getTracer(sessionId)?.log("telegram", { action: "handle:toolUpdate", sessionId, toolId: meta.id, name: meta.name, kind: meta.kind, status: meta.status, viewerLinks: meta.viewerLinks, viewerFilePath: meta.viewerFilePath });
|
|
6008
|
+
const mode = this.outputModeResolver.resolve(
|
|
6009
|
+
this.context.configManager,
|
|
6010
|
+
this.name,
|
|
6011
|
+
sessionId,
|
|
6012
|
+
this.core.sessionManager
|
|
6013
|
+
);
|
|
6014
|
+
const tracker = this.getOrCreateTracker(sessionId, threadId, mode);
|
|
4972
6015
|
await tracker.onToolUpdate(
|
|
4973
6016
|
meta.id ?? "",
|
|
4974
6017
|
meta.status ?? "completed",
|
|
4975
6018
|
meta.viewerLinks,
|
|
4976
|
-
meta.viewerFilePath
|
|
6019
|
+
meta.viewerFilePath,
|
|
6020
|
+
typeof meta.content === "string" ? meta.content : null,
|
|
6021
|
+
meta.rawInput ?? void 0,
|
|
6022
|
+
meta.diffStats
|
|
4977
6023
|
);
|
|
4978
6024
|
}
|
|
4979
|
-
async handlePlan(sessionId, content,
|
|
6025
|
+
async handlePlan(sessionId, content, _verbosity) {
|
|
4980
6026
|
const threadId = this.getThreadId(sessionId);
|
|
4981
6027
|
const meta = content.metadata ?? {};
|
|
4982
6028
|
const entries = meta.entries ?? [];
|
|
4983
|
-
|
|
6029
|
+
this.getTracer(sessionId)?.log("telegram", { action: "handle:plan", sessionId, entryCount: entries.length });
|
|
6030
|
+
const mode = this.outputModeResolver.resolve(
|
|
6031
|
+
this.context.configManager,
|
|
6032
|
+
this.name,
|
|
6033
|
+
sessionId,
|
|
6034
|
+
this.core.sessionManager
|
|
6035
|
+
);
|
|
6036
|
+
const tracker = this.getOrCreateTracker(sessionId, threadId, mode);
|
|
4984
6037
|
await tracker.onPlan(
|
|
4985
6038
|
entries.map((e) => ({
|
|
4986
6039
|
content: e.content,
|
|
@@ -4992,15 +6045,27 @@ ${lines.join("\n")}`;
|
|
|
4992
6045
|
async handleUsage(sessionId, content, verbosity) {
|
|
4993
6046
|
const threadId = this.getThreadId(sessionId);
|
|
4994
6047
|
const meta = content.metadata;
|
|
6048
|
+
this.getTracer(sessionId)?.log("telegram", { action: "handle:usage", sessionId, tokensUsed: meta?.tokensUsed, contextSize: meta?.contextSize, cost: meta?.cost });
|
|
4995
6049
|
await this.draftManager.finalize(sessionId, this.assistantSession?.id);
|
|
4996
|
-
const
|
|
4997
|
-
|
|
6050
|
+
const usageText = formatUsage(meta ?? {}, verbosity);
|
|
6051
|
+
let usageMsgId;
|
|
6052
|
+
try {
|
|
6053
|
+
const result = await this.sendQueue.enqueue(
|
|
6054
|
+
() => this.bot.api.sendMessage(this.telegramConfig.chatId, usageText, {
|
|
6055
|
+
message_thread_id: threadId,
|
|
6056
|
+
parse_mode: "HTML",
|
|
6057
|
+
disable_notification: true
|
|
6058
|
+
})
|
|
6059
|
+
);
|
|
6060
|
+
usageMsgId = result?.message_id;
|
|
6061
|
+
} catch (err) {
|
|
6062
|
+
log12.warn({ err, sessionId }, "Failed to send usage message");
|
|
6063
|
+
}
|
|
4998
6064
|
if (this.notificationTopicId && sessionId !== this.assistantSession?.id) {
|
|
4999
6065
|
const sess = this.core.sessionManager.getSession(sessionId);
|
|
5000
6066
|
const sessionName = sess?.name || "Session";
|
|
5001
6067
|
const chatIdStr = String(this.telegramConfig.chatId);
|
|
5002
6068
|
const numericId = chatIdStr.startsWith("-100") ? chatIdStr.slice(4) : chatIdStr.replace("-", "");
|
|
5003
|
-
const usageMsgId = tracker.getUsageMsgId();
|
|
5004
6069
|
const deepLink = usageMsgId ? `https://t.me/c/${numericId}/${threadId}/${usageMsgId}` : `https://t.me/c/${numericId}/${threadId}`;
|
|
5005
6070
|
const text = `\u2705 <b>${escapeHtml(sessionName)}</b>
|
|
5006
6071
|
Task completed.
|
|
@@ -5017,6 +6082,7 @@ Task completed.
|
|
|
5017
6082
|
}
|
|
5018
6083
|
}
|
|
5019
6084
|
async handleAttachment(sessionId, content) {
|
|
6085
|
+
this.getTracer(sessionId)?.log("telegram", { action: "handle:attachment", sessionId, type: content.attachment?.type, fileName: content.attachment?.fileName });
|
|
5020
6086
|
const threadId = this.getThreadId(sessionId);
|
|
5021
6087
|
if (!content.attachment) return;
|
|
5022
6088
|
const { attachment } = content;
|
|
@@ -5072,6 +6138,7 @@ Task completed.
|
|
|
5072
6138
|
}
|
|
5073
6139
|
}
|
|
5074
6140
|
async handleSessionEnd(sessionId, _content) {
|
|
6141
|
+
this.getTracer(sessionId)?.log("telegram", { action: "handle:sessionEnd", sessionId });
|
|
5075
6142
|
const threadId = this.getThreadId(sessionId);
|
|
5076
6143
|
await this.draftManager.finalize(sessionId, this.assistantSession?.id);
|
|
5077
6144
|
this.draftManager.cleanup(sessionId);
|
|
@@ -5091,6 +6158,7 @@ Task completed.
|
|
|
5091
6158
|
}
|
|
5092
6159
|
}
|
|
5093
6160
|
async handleError(sessionId, content) {
|
|
6161
|
+
this.getTracer(sessionId)?.log("telegram", { action: "handle:error", sessionId, text: content.text });
|
|
5094
6162
|
const threadId = this.getThreadId(sessionId);
|
|
5095
6163
|
await this.draftManager.finalize(sessionId, this.assistantSession?.id);
|
|
5096
6164
|
const tracker = this.sessionTrackers.get(sessionId);
|
|
@@ -5111,6 +6179,7 @@ Task completed.
|
|
|
5111
6179
|
);
|
|
5112
6180
|
}
|
|
5113
6181
|
async handleSystem(sessionId, content) {
|
|
6182
|
+
this.getTracer(sessionId)?.log("telegram", { action: "handle:system", sessionId, text: content.text });
|
|
5114
6183
|
const threadId = this.getThreadId(sessionId);
|
|
5115
6184
|
await this.sendQueue.enqueue(
|
|
5116
6185
|
() => this.bot.api.sendMessage(
|
|
@@ -5125,6 +6194,7 @@ Task completed.
|
|
|
5125
6194
|
);
|
|
5126
6195
|
}
|
|
5127
6196
|
async sendPermissionRequest(sessionId, request) {
|
|
6197
|
+
this.getTracer(sessionId)?.log("telegram", { action: "permission:send", sessionId, requestId: request.id, description: request.description });
|
|
5128
6198
|
log12.info({ sessionId, requestId: request.id }, "Permission request sent");
|
|
5129
6199
|
const session = this.core.sessionManager.getSession(sessionId);
|
|
5130
6200
|
if (!session) return;
|
|
@@ -5133,6 +6203,7 @@ Task completed.
|
|
|
5133
6203
|
);
|
|
5134
6204
|
}
|
|
5135
6205
|
async sendNotification(notification) {
|
|
6206
|
+
this.getTracer(notification.sessionId)?.log("telegram", { action: "notification:send", sessionId: notification.sessionId, type: notification.type });
|
|
5136
6207
|
if (notification.sessionId === this.assistantSession?.id) return;
|
|
5137
6208
|
log12.info(
|
|
5138
6209
|
{ sessionId: notification.sessionId, type: notification.type },
|
|
@@ -5172,12 +6243,14 @@ Task completed.
|
|
|
5172
6243
|
);
|
|
5173
6244
|
}
|
|
5174
6245
|
async createSessionThread(sessionId, name) {
|
|
6246
|
+
this.getTracer(sessionId)?.log("telegram", { action: "thread:create", sessionId, name });
|
|
5175
6247
|
log12.info({ sessionId, name }, "Session topic created");
|
|
5176
6248
|
return String(
|
|
5177
6249
|
await createSessionTopic(this.bot, this.telegramConfig.chatId, name)
|
|
5178
6250
|
);
|
|
5179
6251
|
}
|
|
5180
6252
|
async renameSessionThread(sessionId, newName) {
|
|
6253
|
+
this.getTracer(sessionId)?.log("telegram", { action: "thread:rename", sessionId, newName });
|
|
5181
6254
|
const session = this.core.sessionManager.getSession(sessionId);
|
|
5182
6255
|
if (!session) return;
|
|
5183
6256
|
await renameSessionTopic(
|
|
@@ -5283,10 +6356,14 @@ Task completed.
|
|
|
5283
6356
|
async cleanupSkillCommands(sessionId) {
|
|
5284
6357
|
await this.skillManager.cleanup(sessionId);
|
|
5285
6358
|
}
|
|
6359
|
+
async stripTTSBlock(sessionId) {
|
|
6360
|
+
await this.draftManager.stripPattern(sessionId, /\[TTS\][\s\S]*?\[\/TTS\]/g);
|
|
6361
|
+
}
|
|
5286
6362
|
async archiveSessionTopic(sessionId) {
|
|
6363
|
+
this.getTracer(sessionId)?.log("telegram", { action: "thread:archive", sessionId });
|
|
5287
6364
|
const core = this.core;
|
|
5288
6365
|
const session = core.sessionManager.getSession(sessionId);
|
|
5289
|
-
if (!session)
|
|
6366
|
+
if (!session) throw new Error("Session not found");
|
|
5290
6367
|
const chatId = this.telegramConfig.chatId;
|
|
5291
6368
|
const oldTopicId = Number(session.threadId);
|
|
5292
6369
|
session.archiving = true;
|
|
@@ -5299,12 +6376,29 @@ Task completed.
|
|
|
5299
6376
|
this.sessionTrackers.delete(session.id);
|
|
5300
6377
|
}
|
|
5301
6378
|
await deleteSessionTopic(this.bot, chatId, oldTopicId);
|
|
6379
|
+
const topicName = session.name ?? `Session ${session.id.slice(0, 6)}`;
|
|
6380
|
+
const newTopicId = await createSessionTopic(this.bot, chatId, topicName);
|
|
6381
|
+
session.archiving = false;
|
|
6382
|
+
return String(newTopicId);
|
|
5302
6383
|
}
|
|
5303
6384
|
};
|
|
5304
6385
|
|
|
5305
6386
|
export {
|
|
6387
|
+
STATUS_ICONS,
|
|
6388
|
+
KIND_ICONS,
|
|
6389
|
+
progressBar,
|
|
6390
|
+
formatTokens,
|
|
6391
|
+
stripCodeFences,
|
|
6392
|
+
truncateContent,
|
|
6393
|
+
splitMessage,
|
|
6394
|
+
extractContentText,
|
|
6395
|
+
formatToolSummary,
|
|
6396
|
+
formatToolTitle,
|
|
6397
|
+
resolveToolIcon,
|
|
5306
6398
|
PRODUCT_GUIDE,
|
|
5307
6399
|
SendQueue,
|
|
6400
|
+
MessagingAdapter,
|
|
6401
|
+
BaseRenderer,
|
|
5308
6402
|
TelegramAdapter
|
|
5309
6403
|
};
|
|
5310
|
-
//# sourceMappingURL=chunk-
|
|
6404
|
+
//# sourceMappingURL=chunk-5ZNBNIK3.js.map
|