@bd7pil/ocrc 0.9.0
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/LICENSE +34 -0
- package/README.md +330 -0
- package/dist/cli/host-backends.js +216 -0
- package/dist/cli/host-backends.js.map +1 -0
- package/dist/cli/host.js +185 -0
- package/dist/cli/host.js.map +1 -0
- package/dist/cli/index.js +67 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.js +68 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/install.js +220 -0
- package/dist/cli/install.js.map +1 -0
- package/dist/cli/pair.js +11 -0
- package/dist/cli/pair.js.map +1 -0
- package/dist/cli/uninstall.js +75 -0
- package/dist/cli/uninstall.js.map +1 -0
- package/dist/connectivity/auth/cf-access.js +20 -0
- package/dist/connectivity/auth/cf-access.js.map +1 -0
- package/dist/connectivity/auth/index.js +2 -0
- package/dist/connectivity/auth/index.js.map +1 -0
- package/dist/connectivity/auth/select.js +19 -0
- package/dist/connectivity/auth/select.js.map +1 -0
- package/dist/connectivity/auth/token.js +157 -0
- package/dist/connectivity/auth/token.js.map +1 -0
- package/dist/connectivity/exposure/cloudflared.js +77 -0
- package/dist/connectivity/exposure/cloudflared.js.map +1 -0
- package/dist/connectivity/exposure/index.js +2 -0
- package/dist/connectivity/exposure/index.js.map +1 -0
- package/dist/connectivity/exposure/providers.js +49 -0
- package/dist/connectivity/exposure/providers.js.map +1 -0
- package/dist/connectivity/pairing.js +29 -0
- package/dist/connectivity/pairing.js.map +1 -0
- package/dist/core/agent/acp-backend.js +539 -0
- package/dist/core/agent/acp-backend.js.map +1 -0
- package/dist/core/agent/acp-connect.js +92 -0
- package/dist/core/agent/acp-connect.js.map +1 -0
- package/dist/core/agent/acp-normalizer.js +81 -0
- package/dist/core/agent/acp-normalizer.js.map +1 -0
- package/dist/core/agent/acp-replay.js +89 -0
- package/dist/core/agent/acp-replay.js.map +1 -0
- package/dist/core/agent/acp-store.js +129 -0
- package/dist/core/agent/acp-store.js.map +1 -0
- package/dist/core/agent/backend.js +2 -0
- package/dist/core/agent/backend.js.map +1 -0
- package/dist/core/agent/diff-util.js +70 -0
- package/dist/core/agent/diff-util.js.map +1 -0
- package/dist/core/agent/event.js +12 -0
- package/dist/core/agent/event.js.map +1 -0
- package/dist/core/agent/opencode-backend.js +598 -0
- package/dist/core/agent/opencode-backend.js.map +1 -0
- package/dist/core/agent/opencode-normalizer.js +69 -0
- package/dist/core/agent/opencode-normalizer.js.map +1 -0
- package/dist/core/agent/registry.js +55 -0
- package/dist/core/agent/registry.js.map +1 -0
- package/dist/core/agent/v2-backend.js +176 -0
- package/dist/core/agent/v2-backend.js.map +1 -0
- package/dist/core/card-bus.js +74 -0
- package/dist/core/card-bus.js.map +1 -0
- package/dist/core/channels.js +95 -0
- package/dist/core/channels.js.map +1 -0
- package/dist/core/history.js +91 -0
- package/dist/core/history.js.map +1 -0
- package/dist/core/list-files.js +50 -0
- package/dist/core/list-files.js.map +1 -0
- package/dist/core/opencode-events.js +29 -0
- package/dist/core/opencode-events.js.map +1 -0
- package/dist/core/primary-election.js +91 -0
- package/dist/core/primary-election.js.map +1 -0
- package/dist/core/push.js +152 -0
- package/dist/core/push.js.map +1 -0
- package/dist/core/relay.js +400 -0
- package/dist/core/relay.js.map +1 -0
- package/dist/core/scheduler.js +150 -0
- package/dist/core/scheduler.js.map +1 -0
- package/dist/core/state.js +222 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/stream-accumulator.js +76 -0
- package/dist/core/stream-accumulator.js.map +1 -0
- package/dist/core/structured-card.js +2 -0
- package/dist/core/structured-card.js.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/opencode/global-events.js +57 -0
- package/dist/opencode/global-events.js.map +1 -0
- package/dist/opencode/list-sessions.js +122 -0
- package/dist/opencode/list-sessions.js.map +1 -0
- package/dist/opencode/submit.js +39 -0
- package/dist/opencode/submit.js.map +1 -0
- package/dist/opencode/workspaces.js +51 -0
- package/dist/opencode/workspaces.js.map +1 -0
- package/dist/plugin/config.js +128 -0
- package/dist/plugin/config.js.map +1 -0
- package/dist/plugin/control-plane.js +133 -0
- package/dist/plugin/control-plane.js.map +1 -0
- package/dist/plugin/entry.js +409 -0
- package/dist/plugin/entry.js.map +1 -0
- package/dist/plugin/v2/event-map.js +193 -0
- package/dist/plugin/v2/event-map.js.map +1 -0
- package/dist/plugin/v2/types.js +15 -0
- package/dist/plugin/v2/types.js.map +1 -0
- package/dist/transport/interface.js +2 -0
- package/dist/transport/interface.js.map +1 -0
- package/dist/transport/telegram/esc.js +9 -0
- package/dist/transport/telegram/esc.js.map +1 -0
- package/dist/transport/telegram/handlers/info-commands.js +101 -0
- package/dist/transport/telegram/handlers/info-commands.js.map +1 -0
- package/dist/transport/telegram/handlers.js +1348 -0
- package/dist/transport/telegram/handlers.js.map +1 -0
- package/dist/transport/telegram/i18n/en.js +538 -0
- package/dist/transport/telegram/i18n/en.js.map +1 -0
- package/dist/transport/telegram/i18n/index.js +83 -0
- package/dist/transport/telegram/i18n/index.js.map +1 -0
- package/dist/transport/telegram/i18n/zh.js +538 -0
- package/dist/transport/telegram/i18n/zh.js.map +1 -0
- package/dist/transport/telegram/index.js +792 -0
- package/dist/transport/telegram/index.js.map +1 -0
- package/dist/transport/telegram/main-keyboard.js +36 -0
- package/dist/transport/telegram/main-keyboard.js.map +1 -0
- package/dist/transport/telegram/managers/abort-suppression-manager.js +33 -0
- package/dist/transport/telegram/managers/abort-suppression-manager.js.map +1 -0
- package/dist/transport/telegram/managers/external-input-suppression-manager.js +51 -0
- package/dist/transport/telegram/managers/external-input-suppression-manager.js.map +1 -0
- package/dist/transport/telegram/managers/interaction-manager.js +254 -0
- package/dist/transport/telegram/managers/interaction-manager.js.map +1 -0
- package/dist/transport/telegram/managers/permission-manager.js +242 -0
- package/dist/transport/telegram/managers/permission-manager.js.map +1 -0
- package/dist/transport/telegram/managers/question-manager.js +191 -0
- package/dist/transport/telegram/managers/question-manager.js.map +1 -0
- package/dist/transport/telegram/managers/rename-manager.js +56 -0
- package/dist/transport/telegram/managers/rename-manager.js.map +1 -0
- package/dist/transport/telegram/menus.js +77 -0
- package/dist/transport/telegram/menus.js.map +1 -0
- package/dist/transport/telegram/permission-flow.js +156 -0
- package/dist/transport/telegram/permission-flow.js.map +1 -0
- package/dist/transport/telegram/question-flow.js +224 -0
- package/dist/transport/telegram/question-flow.js.map +1 -0
- package/dist/transport/telegram/render/block-parser.js +365 -0
- package/dist/transport/telegram/render/block-parser.js.map +1 -0
- package/dist/transport/telegram/render/block-plain-text.js +87 -0
- package/dist/transport/telegram/render/block-plain-text.js.map +1 -0
- package/dist/transport/telegram/render/block-splitter.js +152 -0
- package/dist/transport/telegram/render/block-splitter.js.map +1 -0
- package/dist/transport/telegram/render/chunker.js +71 -0
- package/dist/transport/telegram/render/chunker.js.map +1 -0
- package/dist/transport/telegram/render/limits.js +13 -0
- package/dist/transport/telegram/render/limits.js.map +1 -0
- package/dist/transport/telegram/render/markdown-normalizer.js +102 -0
- package/dist/transport/telegram/render/markdown-normalizer.js.map +1 -0
- package/dist/transport/telegram/render/markdown-to-telegram-v2.js +116 -0
- package/dist/transport/telegram/render/markdown-to-telegram-v2.js.map +1 -0
- package/dist/transport/telegram/render/part-signature.js +14 -0
- package/dist/transport/telegram/render/part-signature.js.map +1 -0
- package/dist/transport/telegram/render/pipeline.js +23 -0
- package/dist/transport/telegram/render/pipeline.js.map +1 -0
- package/dist/transport/telegram/render/rich-blocks.js +311 -0
- package/dist/transport/telegram/render/rich-blocks.js.map +1 -0
- package/dist/transport/telegram/render/text-splitter.js +64 -0
- package/dist/transport/telegram/render/text-splitter.js.map +1 -0
- package/dist/transport/telegram/render/types.js +2 -0
- package/dist/transport/telegram/render/types.js.map +1 -0
- package/dist/transport/telegram/renderer.js +305 -0
- package/dist/transport/telegram/renderer.js.map +1 -0
- package/dist/transport/telegram/streaming/duration-formatter.js +68 -0
- package/dist/transport/telegram/streaming/duration-formatter.js.map +1 -0
- package/dist/transport/telegram/streaming/finalize-assistant-response.js +37 -0
- package/dist/transport/telegram/streaming/finalize-assistant-response.js.map +1 -0
- package/dist/transport/telegram/streaming/response-streamer.js +400 -0
- package/dist/transport/telegram/streaming/response-streamer.js.map +1 -0
- package/dist/transport/telegram/streaming/running-tool-tracker.js +150 -0
- package/dist/transport/telegram/streaming/running-tool-tracker.js.map +1 -0
- package/dist/transport/telegram/streaming/stream-throttle.js +57 -0
- package/dist/transport/telegram/streaming/stream-throttle.js.map +1 -0
- package/dist/transport/telegram/streaming/tool-call-streamer.js +390 -0
- package/dist/transport/telegram/streaming/tool-call-streamer.js.map +1 -0
- package/dist/transport/telegram/streaming-render.js +182 -0
- package/dist/transport/telegram/streaming-render.js.map +1 -0
- package/dist/transport/telegram/types/interaction.js +2 -0
- package/dist/transport/telegram/types/interaction.js.map +1 -0
- package/dist/transport/telegram/types/model.js +25 -0
- package/dist/transport/telegram/types/model.js.map +1 -0
- package/dist/transport/telegram/types/permission.js +2 -0
- package/dist/transport/telegram/types/permission.js.map +1 -0
- package/dist/transport/telegram/types/question.js +2 -0
- package/dist/transport/telegram/types/question.js.map +1 -0
- package/dist/transport/telegram/types/rename.js +2 -0
- package/dist/transport/telegram/types/rename.js.map +1 -0
- package/dist/transport/telegram/types/scheduled-task.js +23 -0
- package/dist/transport/telegram/types/scheduled-task.js.map +1 -0
- package/dist/transport/telegram/types/session.js +2 -0
- package/dist/transport/telegram/types/session.js.map +1 -0
- package/dist/transport/telegram/ui.js +28 -0
- package/dist/transport/telegram/ui.js.map +1 -0
- package/dist/transport/web/index.js +148 -0
- package/dist/transport/web/index.js.map +1 -0
- package/dist/transport/web/middleware/cf-access.js +104 -0
- package/dist/transport/web/middleware/cf-access.js.map +1 -0
- package/dist/transport/web/opencode-config.js +15 -0
- package/dist/transport/web/opencode-config.js.map +1 -0
- package/dist/transport/web/routes/abort.js +12 -0
- package/dist/transport/web/routes/abort.js.map +1 -0
- package/dist/transport/web/routes/approval.js +16 -0
- package/dist/transport/web/routes/approval.js.map +1 -0
- package/dist/transport/web/routes/catalog.js +11 -0
- package/dist/transport/web/routes/catalog.js.map +1 -0
- package/dist/transport/web/routes/channels.js +53 -0
- package/dist/transport/web/routes/channels.js.map +1 -0
- package/dist/transport/web/routes/commands.js +15 -0
- package/dist/transport/web/routes/commands.js.map +1 -0
- package/dist/transport/web/routes/context.js +17 -0
- package/dist/transport/web/routes/context.js.map +1 -0
- package/dist/transport/web/routes/controls.js +34 -0
- package/dist/transport/web/routes/controls.js.map +1 -0
- package/dist/transport/web/routes/create-session.js +21 -0
- package/dist/transport/web/routes/create-session.js.map +1 -0
- package/dist/transport/web/routes/diff.js +7 -0
- package/dist/transport/web/routes/diff.js.map +1 -0
- package/dist/transport/web/routes/files.js +22 -0
- package/dist/transport/web/routes/files.js.map +1 -0
- package/dist/transport/web/routes/logs.js +9 -0
- package/dist/transport/web/routes/logs.js.map +1 -0
- package/dist/transport/web/routes/m8.js +69 -0
- package/dist/transport/web/routes/m8.js.map +1 -0
- package/dist/transport/web/routes/mcp.js +7 -0
- package/dist/transport/web/routes/mcp.js.map +1 -0
- package/dist/transport/web/routes/message.js +32 -0
- package/dist/transport/web/routes/message.js.map +1 -0
- package/dist/transport/web/routes/overrides.js +20 -0
- package/dist/transport/web/routes/overrides.js.map +1 -0
- package/dist/transport/web/routes/question.js +32 -0
- package/dist/transport/web/routes/question.js.map +1 -0
- package/dist/transport/web/routes/rename.js +12 -0
- package/dist/transport/web/routes/rename.js.map +1 -0
- package/dist/transport/web/routes/schedules.js +28 -0
- package/dist/transport/web/routes/schedules.js.map +1 -0
- package/dist/transport/web/routes/session.js +20 -0
- package/dist/transport/web/routes/session.js.map +1 -0
- package/dist/transport/web/routes/sessions.js +25 -0
- package/dist/transport/web/routes/sessions.js.map +1 -0
- package/dist/transport/web/routes/subagents.js +11 -0
- package/dist/transport/web/routes/subagents.js.map +1 -0
- package/dist/transport/web/routes/suggestions.js +7 -0
- package/dist/transport/web/routes/suggestions.js.map +1 -0
- package/dist/transport/web/routes/todo.js +7 -0
- package/dist/transport/web/routes/todo.js.map +1 -0
- package/dist/transport/web/routes/version.js +5 -0
- package/dist/transport/web/routes/version.js.map +1 -0
- package/dist/transport/web/routes/workspaces.js +7 -0
- package/dist/transport/web/routes/workspaces.js.map +1 -0
- package/dist/transport/web/server.js +111 -0
- package/dist/transport/web/server.js.map +1 -0
- package/dist/transport/web/session-summary.js +46 -0
- package/dist/transport/web/session-summary.js.map +1 -0
- package/dist/transport/web/ws-hub.js +83 -0
- package/dist/transport/web/ws-hub.js.map +1 -0
- package/dist/utils/logger.js +105 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/markdown.js +129 -0
- package/dist/utils/markdown.js.map +1 -0
- package/dist/utils/paths.js +18 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/version.js +44 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +91 -0
- package/web/dist/_app/env.js +1 -0
- package/web/dist/_app/immutable/assets/0.DxN3RsuG.css +1 -0
- package/web/dist/_app/immutable/assets/2.BNuGfmZP.css +1 -0
- package/web/dist/_app/immutable/assets/3.CTDprntu.css +1 -0
- package/web/dist/_app/immutable/chunks/BUpwHpMJ.js +1 -0
- package/web/dist/_app/immutable/chunks/BjY4dxcB.js +2 -0
- package/web/dist/_app/immutable/chunks/C2FuqD3s.js +1 -0
- package/web/dist/_app/immutable/chunks/CUHGq08X.js +2 -0
- package/web/dist/_app/immutable/chunks/CWj6FrbW.js +1 -0
- package/web/dist/_app/immutable/chunks/ClvoqtGj.js +1 -0
- package/web/dist/_app/immutable/chunks/DIEDQ_hk.js +1 -0
- package/web/dist/_app/immutable/entry/app.BoRpcVMj.js +2 -0
- package/web/dist/_app/immutable/entry/start.Cj-PQNTq.js +1 -0
- package/web/dist/_app/immutable/nodes/0.y9YEms5p.js +3 -0
- package/web/dist/_app/immutable/nodes/1.CPhhiRM2.js +1 -0
- package/web/dist/_app/immutable/nodes/2.B_c84Mc9.js +1 -0
- package/web/dist/_app/immutable/nodes/3.ClTd0J3D.js +64 -0
- package/web/dist/_app/version.json +1 -0
- package/web/dist/apple-touch-icon.png +0 -0
- package/web/dist/favicon.png +0 -0
- package/web/dist/favicon.svg +17 -0
- package/web/dist/icon-192.png +0 -0
- package/web/dist/icon-512-maskable.png +0 -0
- package/web/dist/icon-512.png +0 -0
- package/web/dist/index.html +73 -0
- package/web/dist/manifest.webmanifest +28 -0
- package/web/dist/service-worker.js +1 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { markdownToTelegramHtml } from '../../utils/markdown.js';
|
|
2
|
+
import { createLogger } from '../../utils/logger.js';
|
|
3
|
+
const log = createLogger('tg-renderer');
|
|
4
|
+
const RESERVE_META = 200;
|
|
5
|
+
const RESERVE_ANSWER_FRAC = 0.7;
|
|
6
|
+
const DEFAULT_CHUNK_SOFT_LIMIT = 3500;
|
|
7
|
+
/** Pause between paginated chunks to stay under Telegram's send-rate limits. */
|
|
8
|
+
const CHUNK_DELAY_MS = 300;
|
|
9
|
+
/** Max retries when Telegram answers 429 (rate limited). */
|
|
10
|
+
const MAX_429_RETRIES = 3;
|
|
11
|
+
/** Cap on the server-provided retry_after wait. */
|
|
12
|
+
const MAX_RETRY_AFTER_MS = 60_000;
|
|
13
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
14
|
+
/**
|
|
15
|
+
* Extract the retry_after wait (ms) from a 429 error, or undefined
|
|
16
|
+
* for any other error. Telegraf surfaces it as
|
|
17
|
+
* err.response.parameters.retry_after (seconds).
|
|
18
|
+
*/
|
|
19
|
+
function retryAfterMs(err) {
|
|
20
|
+
const e = err;
|
|
21
|
+
if (e?.response?.error_code === 429 && typeof e.response.parameters?.retry_after === 'number') {
|
|
22
|
+
return Math.min(e.response.parameters.retry_after * 1000, MAX_RETRY_AFTER_MS);
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
function escHtml(s) {
|
|
27
|
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
28
|
+
}
|
|
29
|
+
/** Strip HTML tags and unescape entities — used for the plain-text send fallback. */
|
|
30
|
+
function stripTags(html) {
|
|
31
|
+
return html
|
|
32
|
+
.replace(/<[^>]+>/g, '')
|
|
33
|
+
.replace(/</g, '<')
|
|
34
|
+
.replace(/>/g, '>')
|
|
35
|
+
.replace(/&/g, '&');
|
|
36
|
+
}
|
|
37
|
+
/** Wrap a promise with a 10s timeout to prevent hanging on stuck TCP connections. */
|
|
38
|
+
async function withTimeout(p, label) {
|
|
39
|
+
let timer;
|
|
40
|
+
try {
|
|
41
|
+
return await Promise.race([
|
|
42
|
+
p,
|
|
43
|
+
new Promise((_, reject) => {
|
|
44
|
+
timer = setTimeout(() => reject(new Error(`${label} timeout`)), 10_000);
|
|
45
|
+
}),
|
|
46
|
+
]);
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
// Clear the timeout when the send wins the race — otherwise the timer
|
|
50
|
+
// stays alive for 10s per message and rejects into the void.
|
|
51
|
+
if (timer)
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function fmtK(n) {
|
|
56
|
+
return n >= 1000 ? `${(n / 1000).toFixed(1)}k` : String(n);
|
|
57
|
+
}
|
|
58
|
+
function metaFooter(meta) {
|
|
59
|
+
const parts = [];
|
|
60
|
+
if (typeof meta.cost === 'number')
|
|
61
|
+
parts.push(`💰 $${meta.cost.toFixed(3)}`);
|
|
62
|
+
if (meta.tokens)
|
|
63
|
+
parts.push(`↑${fmtK(meta.tokens.input)} ↓${fmtK(meta.tokens.output)}`);
|
|
64
|
+
if (meta.agent)
|
|
65
|
+
parts.push(meta.agent);
|
|
66
|
+
if (meta.model)
|
|
67
|
+
parts.push(meta.model);
|
|
68
|
+
return parts.join(' · ');
|
|
69
|
+
}
|
|
70
|
+
/** Hard-split a single line that is itself longer than perChunk. */
|
|
71
|
+
function hardWrap(line, perChunk) {
|
|
72
|
+
if (line.length <= perChunk)
|
|
73
|
+
return [line];
|
|
74
|
+
const parts = [];
|
|
75
|
+
for (let i = 0; i < line.length; i += perChunk)
|
|
76
|
+
parts.push(line.slice(i, i + perChunk));
|
|
77
|
+
return parts;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Split markdown into chunks under perChunk, breaking only at line boundaries.
|
|
81
|
+
* Breaking at line boundaries (never mid-line) avoids splitting an inline bold
|
|
82
|
+
* or code token across two messages, which renders as unbalanced HTML and trips
|
|
83
|
+
* Telegram's "can't parse entities" 400. A fenced code block smaller than
|
|
84
|
+
* perChunk stays intact; one larger than perChunk is broken (each chunk is
|
|
85
|
+
* still valid HTML — markdownToTelegramHtml closes a dangling fence).
|
|
86
|
+
*/
|
|
87
|
+
export function splitMarkdown(md, perChunk) {
|
|
88
|
+
const out = [];
|
|
89
|
+
let cur = [];
|
|
90
|
+
let curLen = 0;
|
|
91
|
+
const flush = () => { if (cur.length) {
|
|
92
|
+
out.push(cur.join('\n'));
|
|
93
|
+
cur = [];
|
|
94
|
+
curLen = 0;
|
|
95
|
+
} };
|
|
96
|
+
for (const rawLine of md.split('\n')) {
|
|
97
|
+
for (const line of hardWrap(rawLine, perChunk)) {
|
|
98
|
+
if (cur.length > 0 && curLen + line.length + 1 > perChunk)
|
|
99
|
+
flush();
|
|
100
|
+
cur.push(line);
|
|
101
|
+
curLen += line.length + 1;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
flush();
|
|
105
|
+
return out.length ? out : [''];
|
|
106
|
+
}
|
|
107
|
+
function collapseTools(tools) {
|
|
108
|
+
if (tools.length <= 7)
|
|
109
|
+
return tools;
|
|
110
|
+
const running = tools.filter((t) => t.status === 'running');
|
|
111
|
+
const done = tools.filter((t) => t.status !== 'running');
|
|
112
|
+
const tailCount = tools.length <= 15 ? 5 : 4;
|
|
113
|
+
const firstCount = tools.length <= 15 ? 2 : 1;
|
|
114
|
+
const first = done.slice(0, firstCount);
|
|
115
|
+
const tailDone = done.slice(firstCount).slice(-(tailCount - Math.min(running.length, tailCount)));
|
|
116
|
+
const tail = [...tailDone, ...running].slice(-tailCount);
|
|
117
|
+
const middleCount = tools.length - first.length - tail.length;
|
|
118
|
+
if (middleCount <= 0)
|
|
119
|
+
return [...first, ...tail];
|
|
120
|
+
return [...first, { tool: '__more__', args: `${middleCount} more tool calls`, status: 'done' }, ...tail];
|
|
121
|
+
}
|
|
122
|
+
/** Extract flat markdown string from blocks (concatenate all text blocks). */
|
|
123
|
+
function blocksToText(blocks) {
|
|
124
|
+
return blocks
|
|
125
|
+
.filter((b) => b.type === 'text')
|
|
126
|
+
.map(b => b.text)
|
|
127
|
+
.join('');
|
|
128
|
+
}
|
|
129
|
+
/** Extract ToolCall[] from blocks. */
|
|
130
|
+
function blocksToTools(blocks) {
|
|
131
|
+
return blocks
|
|
132
|
+
.filter((b) => b.type === 'tool')
|
|
133
|
+
.map(b => ({ tool: b.tool, args: b.args, status: b.status }));
|
|
134
|
+
}
|
|
135
|
+
export class TelegramSessionRenderer {
|
|
136
|
+
chatId;
|
|
137
|
+
sessionId;
|
|
138
|
+
bot;
|
|
139
|
+
thinkingMessageId;
|
|
140
|
+
chunkSoftLimit;
|
|
141
|
+
constructor(opts) {
|
|
142
|
+
this.chatId = opts.chatId;
|
|
143
|
+
this.sessionId = opts.sessionId;
|
|
144
|
+
this.bot = opts.bot;
|
|
145
|
+
this.chunkSoftLimit = opts.chunkSoftLimit ?? Number(process.env.TG_CHUNK_SOFT_LIMIT ?? DEFAULT_CHUNK_SOFT_LIMIT);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* sendMessage with a 10s timeout to prevent TCP hang. On a Telegram 429
|
|
149
|
+
* (rate limit), wait the server-provided retry_after and resend. If Telegram
|
|
150
|
+
* rejects the HTML (can't parse entities), retry once as plain text so the
|
|
151
|
+
* content is still delivered rather than silently dropped.
|
|
152
|
+
*/
|
|
153
|
+
async sendTimed(text, extra) {
|
|
154
|
+
for (let attempt = 0;; attempt++) {
|
|
155
|
+
try {
|
|
156
|
+
return await withTimeout(this.bot.sendMessage(this.chatId, text, extra ?? {}), 'sendMessage');
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
const wait = retryAfterMs(err);
|
|
160
|
+
if (wait !== undefined && attempt < MAX_429_RETRIES) {
|
|
161
|
+
log.warn(`sendMessage rate-limited (429), retrying in ${wait}ms`);
|
|
162
|
+
await sleep(wait);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
const msg = err.message ?? '';
|
|
166
|
+
if (extra && 'parse_mode' in extra && /parse entities|parse_mode|unsupported start tag|can't find end/i.test(msg)) {
|
|
167
|
+
log.warn(`sendMessage HTML parse error, retrying as plain text: ${msg}`);
|
|
168
|
+
const { parse_mode, ...rest } = extra;
|
|
169
|
+
return await this.sendTimed(stripTags(text), rest);
|
|
170
|
+
}
|
|
171
|
+
throw err;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
async onCard(card) {
|
|
176
|
+
switch (card.kind) {
|
|
177
|
+
case 'thinking': return this.startThinking();
|
|
178
|
+
case 'streaming': return; // no-op — Telegram only delivers final result
|
|
179
|
+
case 'assistant': return this.finalize(card.blocks, card.meta);
|
|
180
|
+
case 'error': return this.markError(card.message);
|
|
181
|
+
case 'user': {
|
|
182
|
+
// The user already sees their own message in the Telegram chat — don't
|
|
183
|
+
// echo it back. Still show prompts that originated elsewhere (e.g. web),
|
|
184
|
+
// so a Telegram observer sees what was asked from another surface.
|
|
185
|
+
if (card.origin === 'telegram')
|
|
186
|
+
return;
|
|
187
|
+
const userText = card.text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
188
|
+
await this.sendTimed(`<i>${userText.slice(0, 200)}${userText.length > 200 ? '…' : ''}</i>`, { parse_mode: 'HTML' });
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
case 'think-stream': return; // disabled
|
|
192
|
+
case 'status':
|
|
193
|
+
case 'approval': return; // Handled by command handlers
|
|
194
|
+
case 'info': return this.sendInfo(card.title, card.sections);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
async startThinking() {
|
|
198
|
+
try {
|
|
199
|
+
const sent = await this.sendTimed('⏳ Working…', { parse_mode: 'HTML' });
|
|
200
|
+
this.thinkingMessageId = String(sent.message_id);
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
log.warn('startThinking: initial message failed, continuing without placeholder', err.message);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/** Delete the '⏳ Working…' placeholder if one is pending. */
|
|
207
|
+
async clearThinkingPlaceholder() {
|
|
208
|
+
if (this.thinkingMessageId) {
|
|
209
|
+
await this.bot.deleteMessage(this.chatId, Number(this.thinkingMessageId)).catch(() => { });
|
|
210
|
+
this.thinkingMessageId = undefined;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
async finalize(blocks, meta) {
|
|
214
|
+
try {
|
|
215
|
+
await this.clearThinkingPlaceholder();
|
|
216
|
+
const md = blocksToText(blocks);
|
|
217
|
+
const tools = blocksToTools(blocks);
|
|
218
|
+
const PER_CHUNK = Math.floor((this.chunkSoftLimit - RESERVE_META) * RESERVE_ANSWER_FRAC);
|
|
219
|
+
const pieces = splitMarkdown(md, PER_CHUNK);
|
|
220
|
+
log.debug(`finalize: md=${md.length} chars, ${pieces.length} piece(s)`);
|
|
221
|
+
for (let i = 0; i < pieces.length; i++) {
|
|
222
|
+
// Throttle back-to-back chunk sends to avoid tripping Telegram's rate limit.
|
|
223
|
+
if (i > 0)
|
|
224
|
+
await sleep(CHUNK_DELAY_MS);
|
|
225
|
+
const isLast = i === pieces.length - 1;
|
|
226
|
+
const body = this.renderChunkBody(pieces[i], i === 0 ? tools : [], isLast ? { meta } : {});
|
|
227
|
+
await this.sendTimed(body, { parse_mode: 'HTML' });
|
|
228
|
+
log.debug(`finalize: piece ${i + 1}/${pieces.length} sent (len=${body.length})`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
log.error('finalize: FATAL error, attempting last-resort send', err.message);
|
|
233
|
+
try {
|
|
234
|
+
const md = blocksToText(blocks);
|
|
235
|
+
if (md) {
|
|
236
|
+
await this.sendTimed(md.slice(0, 3800), { parse_mode: 'HTML' });
|
|
237
|
+
log.info('finalize: last-resort send succeeded');
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
catch (e2) {
|
|
241
|
+
log.error('finalize: last-resort send also failed', e2.message);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
async markError(message) {
|
|
246
|
+
await this.clearThinkingPlaceholder();
|
|
247
|
+
const text = `❌ <b>Error</b>\n\n<code>${escHtml(message)}</code>`;
|
|
248
|
+
await this.sendTimed(text, { parse_mode: 'HTML' });
|
|
249
|
+
}
|
|
250
|
+
async sendInfo(title, sections) {
|
|
251
|
+
const lines = [];
|
|
252
|
+
if (title)
|
|
253
|
+
lines.push(`<b>${escHtml(title)}</b>`);
|
|
254
|
+
for (const s of sections) {
|
|
255
|
+
if (s.heading)
|
|
256
|
+
lines.push(`<u>${escHtml(s.heading)}</u>`);
|
|
257
|
+
lines.push(markdownToTelegramHtml(s.body));
|
|
258
|
+
}
|
|
259
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
260
|
+
try {
|
|
261
|
+
await this.sendTimed(lines.join('\n'), { parse_mode: 'HTML' });
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
catch (err) {
|
|
265
|
+
const msg = err.message;
|
|
266
|
+
if (attempt < 2 && /ECONNRESET|ETIMEDOUT|network/i.test(msg)) {
|
|
267
|
+
log.warn(`sendInfo retry ${attempt + 1}/3: ${msg}`);
|
|
268
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
log.warn('sendInfo failed', msg);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
renderChunkBody(md, tools, opts) {
|
|
278
|
+
const lines = [];
|
|
279
|
+
const collapsed = collapseTools(tools);
|
|
280
|
+
if (collapsed.length > 0) {
|
|
281
|
+
for (const t of collapsed) {
|
|
282
|
+
if (t.tool === '__more__') {
|
|
283
|
+
lines.push(`… ${t.args}`);
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
const mark = t.status === 'done' ? '✓' : t.status === 'error' ? '✗' : '…';
|
|
287
|
+
lines.push(`▸ ${t.tool}${t.args ? ` · ${escHtml(t.args)}` : ''} ${mark}`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
lines.push('');
|
|
291
|
+
}
|
|
292
|
+
if (md)
|
|
293
|
+
lines.push(markdownToTelegramHtml(md));
|
|
294
|
+
if (opts.meta) {
|
|
295
|
+
const footer = metaFooter(opts.meta);
|
|
296
|
+
if (footer) {
|
|
297
|
+
lines.push('');
|
|
298
|
+
lines.push('──────────');
|
|
299
|
+
lines.push(`<i>${escHtml(footer)}</i>`);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return lines.join('\n');
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../../src/transport/telegram/renderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const SECOND_MS = 1000;
|
|
2
|
+
const MINUTE_MS = 60 * SECOND_MS;
|
|
3
|
+
const HOUR_MS = 60 * MINUTE_MS;
|
|
4
|
+
const TEN_MINUTES_MS = 10 * MINUTE_MS;
|
|
5
|
+
const FIVE_MINUTES_MS = 5 * MINUTE_MS;
|
|
6
|
+
const FIFTEEN_MINUTES_MS = 15 * MINUTE_MS;
|
|
7
|
+
const TEN_SECONDS_MS = 10 * SECOND_MS;
|
|
8
|
+
/** Tool calls shorter than this are rendered exactly as before, without elapsed time. */
|
|
9
|
+
export const TOOL_ELAPSED_THRESHOLD_MS = 20 * SECOND_MS;
|
|
10
|
+
/** Prefix every rendered duration shares with the assistant run footer. */
|
|
11
|
+
export const DURATION_ICON = "🕒";
|
|
12
|
+
/** Marks a step that is still running, as the compact progress header does. */
|
|
13
|
+
export const RUNNING_ICON = "⏳";
|
|
14
|
+
/**
|
|
15
|
+
* Appends a duration the way the assistant run footer does. Composed in code
|
|
16
|
+
* rather than through i18n: there is no word to translate, only placeholders,
|
|
17
|
+
* a separator and two icons.
|
|
18
|
+
*/
|
|
19
|
+
export function appendDuration(text, elapsed) {
|
|
20
|
+
return `${text} · ${DURATION_ICON} ${elapsed}`;
|
|
21
|
+
}
|
|
22
|
+
function floorTo(value, step) {
|
|
23
|
+
return Math.floor(value / step) * step;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Shared duration format: `1h 2m 3s`. Originally written for the assistant run
|
|
27
|
+
* footer and kept here so every place that shows a duration reads the same.
|
|
28
|
+
*/
|
|
29
|
+
export function formatDuration(elapsedMs) {
|
|
30
|
+
const safeElapsedMs = Math.max(0, Math.round(elapsedMs));
|
|
31
|
+
const totalSeconds = Math.floor(safeElapsedMs / 1000);
|
|
32
|
+
const hours = Math.floor(totalSeconds / 3600);
|
|
33
|
+
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
|
34
|
+
const seconds = totalSeconds % 60;
|
|
35
|
+
const parts = [];
|
|
36
|
+
if (hours > 0)
|
|
37
|
+
parts.push(`${hours}h`);
|
|
38
|
+
if (minutes > 0)
|
|
39
|
+
parts.push(`${minutes}m`);
|
|
40
|
+
if (seconds > 0 || parts.length === 0)
|
|
41
|
+
parts.push(`${seconds}s`);
|
|
42
|
+
return parts.join(" ");
|
|
43
|
+
}
|
|
44
|
+
/** Reads as "longer than N hours" in the same notation, e.g. `>24h`. */
|
|
45
|
+
export function formatDurationOverHours(hours) {
|
|
46
|
+
return `>${hours}h`;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Rounds elapsed time down to a display step that grows with the value. Live
|
|
50
|
+
* timers are rendered from the bucketed value, so the message is only edited
|
|
51
|
+
* when the shown number actually changes.
|
|
52
|
+
*/
|
|
53
|
+
export function bucketElapsedMs(elapsedMs) {
|
|
54
|
+
if (!Number.isFinite(elapsedMs) || elapsedMs <= 0) {
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
if (elapsedMs < MINUTE_MS) {
|
|
58
|
+
return floorTo(elapsedMs, TEN_SECONDS_MS);
|
|
59
|
+
}
|
|
60
|
+
if (elapsedMs < TEN_MINUTES_MS) {
|
|
61
|
+
return floorTo(elapsedMs, MINUTE_MS);
|
|
62
|
+
}
|
|
63
|
+
if (elapsedMs < HOUR_MS) {
|
|
64
|
+
return floorTo(elapsedMs, FIVE_MINUTES_MS);
|
|
65
|
+
}
|
|
66
|
+
return floorTo(elapsedMs, FIFTEEN_MINUTES_MS);
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=duration-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duration-formatter.js","sourceRoot":"","sources":["../../../../src/transport/telegram/streaming/duration-formatter.ts"],"names":[],"mappings":"AAAA,MAAM,SAAS,GAAG,IAAI,CAAC;AACvB,MAAM,SAAS,GAAG,EAAE,GAAG,SAAS,CAAC;AACjC,MAAM,OAAO,GAAG,EAAE,GAAG,SAAS,CAAC;AAE/B,MAAM,cAAc,GAAG,EAAE,GAAG,SAAS,CAAC;AACtC,MAAM,eAAe,GAAG,CAAC,GAAG,SAAS,CAAC;AACtC,MAAM,kBAAkB,GAAG,EAAE,GAAG,SAAS,CAAC;AAC1C,MAAM,cAAc,GAAG,EAAE,GAAG,SAAS,CAAC;AAEtC,yFAAyF;AACzF,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,GAAG,SAAS,CAAC;AAExD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAElC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAC;AAEhC;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,OAAe;IAC1D,OAAO,GAAG,IAAI,MAAM,aAAa,IAAI,OAAO,EAAE,CAAC;AACjD,CAAC;AAED,SAAS,OAAO,CAAC,KAAa,EAAE,IAAY;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IACzD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAEtD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,YAAY,GAAG,EAAE,CAAC;IAElC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,KAAK,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IACvC,IAAI,OAAO,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC;IAC3C,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC;IAEjE,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,OAAO,IAAI,KAAK,GAAG,CAAC;AACtB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,SAAiB;IAC/C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QAClD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,SAAS,GAAG,SAAS,EAAE,CAAC;QAC1B,OAAO,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAC5C,CAAC;IAED,IAAI,SAAS,GAAG,cAAc,EAAE,CAAC;QAC/B,OAAO,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACvC,CAAC;IAED,IAAI,SAAS,GAAG,OAAO,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,OAAO,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createLogger } from "../../../utils/logger.js";
|
|
2
|
+
const logger = createLogger("stream");
|
|
3
|
+
export async function finalizeAssistantResponse({ sessionId, messageId, messageText, responseStreamer, flushPendingServiceMessages, prepareStreamingPayload, renderFinalParts, getReplyKeyboard, notifyFirstFinalPart = false, sendRenderedPart, }) {
|
|
4
|
+
logger.debug(`[FinalizeResponse] Final assistant raw text received: session=${sessionId}, message=${messageId}`, messageText);
|
|
5
|
+
const keyboard = getReplyKeyboard();
|
|
6
|
+
const replyOptions = keyboard ? { reply_markup: keyboard } : undefined;
|
|
7
|
+
const silentReplyOptions = {
|
|
8
|
+
disable_notification: true,
|
|
9
|
+
...(replyOptions ?? {}),
|
|
10
|
+
};
|
|
11
|
+
const streamSendOptions = {
|
|
12
|
+
...silentReplyOptions,
|
|
13
|
+
};
|
|
14
|
+
const preparedStreamPayload = prepareStreamingPayload(messageText);
|
|
15
|
+
if (preparedStreamPayload) {
|
|
16
|
+
preparedStreamPayload.sendOptions = streamSendOptions;
|
|
17
|
+
preparedStreamPayload.editOptions = undefined;
|
|
18
|
+
}
|
|
19
|
+
const result = notifyFirstFinalPart
|
|
20
|
+
? await responseStreamer.complete(sessionId, messageId, preparedStreamPayload ?? undefined, {
|
|
21
|
+
notifyFirstCompletePart: true,
|
|
22
|
+
})
|
|
23
|
+
: await responseStreamer.complete(sessionId, messageId, preparedStreamPayload ?? undefined);
|
|
24
|
+
await flushPendingServiceMessages();
|
|
25
|
+
if (result.streamed) {
|
|
26
|
+
logger.debug(`[FinalizeResponse] Finalized streamed assistant message in place: session=${sessionId}, message=${messageId}, telegramMessages=${result.telegramMessageIds.length}`);
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
const parts = renderFinalParts(messageText);
|
|
30
|
+
let notifyNextPart = notifyFirstFinalPart;
|
|
31
|
+
for (const part of parts) {
|
|
32
|
+
await sendRenderedPart(part, notifyNextPart ? replyOptions : silentReplyOptions);
|
|
33
|
+
notifyNextPart = false;
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=finalize-assistant-response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finalize-assistant-response.js","sourceRoot":"","sources":["../../../../src/transport/telegram/streaming/finalize-assistant-response.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;AAwBtC,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,EAC9C,SAAS,EACT,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,2BAA2B,EAC3B,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,GAAG,KAAK,EAC5B,gBAAgB,GACiB;IACjC,MAAM,CAAC,KAAK,CACV,iEAAiE,SAAS,aAAa,SAAS,EAAE,EAClG,WAAW,CACZ,CAAC;IAEF,MAAM,QAAQ,GAAG,gBAAgB,EAAE,CAAC;IACpC,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACvE,MAAM,kBAAkB,GAAG;QACzB,oBAAoB,EAAE,IAAI;QAC1B,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;KACxB,CAAC;IACF,MAAM,iBAAiB,GAAG;QACxB,GAAG,kBAAkB;KACoB,CAAC;IAE5C,MAAM,qBAAqB,GAAG,uBAAuB,CAAC,WAAW,CAAC,CAAC;IACnE,IAAI,qBAAqB,EAAE,CAAC;QAC1B,qBAAqB,CAAC,WAAW,GAAG,iBAAiB,CAAC;QACtD,qBAAqB,CAAC,WAAW,GAAG,SAAS,CAAC;IAChD,CAAC;IAED,MAAM,MAAM,GAAG,oBAAoB;QACjC,CAAC,CAAC,MAAM,gBAAgB,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,qBAAqB,IAAI,SAAS,EAAE;YACxF,uBAAuB,EAAE,IAAI;SAC9B,CAAC;QACJ,CAAC,CAAC,MAAM,gBAAgB,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,qBAAqB,IAAI,SAAS,CAAC,CAAC;IAE9F,MAAM,2BAA2B,EAAE,CAAC;IAEpC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,MAAM,CAAC,KAAK,CACV,6EAA6E,SAAS,aAAa,SAAS,sBAAsB,MAAM,CAAC,kBAAkB,CAAC,MAAM,EAAE,CACrK,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;IAE5C,IAAI,cAAc,GAAG,oBAAoB,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;QACjF,cAAc,GAAG,KAAK,CAAC;IACzB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|