@poolzin/pool-bot 2026.2.0 → 2026.2.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/CHANGELOG.md +118 -0
- package/README-header.png +0 -0
- package/dist/agents/bash-tools.exec.js +76 -25
- package/dist/agents/cli-runner/helpers.js +9 -11
- package/dist/agents/context.js +1 -1
- package/dist/agents/identity.js +47 -7
- package/dist/agents/memory-search.js +25 -8
- package/dist/agents/model-catalog.js +1 -1
- package/dist/agents/model-selection.js +21 -0
- package/dist/agents/pi-embedded-block-chunker.js +117 -42
- package/dist/agents/pi-embedded-helpers/errors.js +183 -78
- package/dist/agents/pi-embedded-helpers.js +1 -1
- package/dist/agents/pi-embedded-runner/compact.js +8 -10
- package/dist/agents/pi-embedded-runner/model.js +62 -3
- package/dist/agents/pi-embedded-runner/run/attempt.js +21 -11
- package/dist/agents/pi-embedded-runner/run.js +199 -46
- package/dist/agents/pi-embedded-runner/system-prompt.js +10 -2
- package/dist/agents/pi-embedded-subscribe.js +118 -29
- package/dist/agents/pi-tools.js +10 -5
- package/dist/agents/poolbot-tools.js +15 -10
- package/dist/agents/sandbox-paths.js +31 -0
- package/dist/agents/session-tool-result-guard.js +94 -15
- package/dist/agents/shell-utils.js +51 -0
- package/dist/agents/skills/bundled-context.js +23 -0
- package/dist/agents/skills/bundled-dir.js +41 -7
- package/dist/agents/skills-install.js +60 -23
- package/dist/agents/subagent-announce.js +79 -34
- package/dist/agents/tool-policy.conformance.js +14 -0
- package/dist/agents/tool-policy.js +24 -0
- package/dist/agents/tools/cron-tool.js +166 -19
- package/dist/agents/tools/discord-actions-presence.js +78 -0
- package/dist/agents/tools/image-tool.js +1 -1
- package/dist/agents/tools/message-tool.js +56 -2
- package/dist/agents/tools/sessions-history-tool.js +69 -1
- package/dist/agents/tools/web-search.js +211 -42
- package/dist/agents/usage.js +23 -1
- package/dist/agents/workspace-run.js +67 -0
- package/dist/agents/workspace-templates.js +44 -0
- package/dist/auto-reply/command-auth.js +121 -6
- package/dist/auto-reply/envelope.js +74 -82
- package/dist/auto-reply/reply/commands-compact.js +1 -0
- package/dist/auto-reply/reply/commands-context-report.js +1 -0
- package/dist/auto-reply/reply/commands-context.js +1 -0
- package/dist/auto-reply/reply/commands-models.js +107 -60
- package/dist/auto-reply/reply/commands-ptt.js +171 -0
- package/dist/auto-reply/reply/get-reply-run.js +2 -1
- package/dist/auto-reply/reply/inbound-context.js +5 -1
- package/dist/auto-reply/reply/mentions.js +1 -1
- package/dist/auto-reply/reply/model-selection.js +3 -3
- package/dist/auto-reply/thinking.js +88 -43
- package/dist/browser/bridge-server.js +13 -0
- package/dist/browser/cdp.helpers.js +38 -24
- package/dist/browser/client-fetch.js +50 -7
- package/dist/browser/config.js +1 -10
- package/dist/browser/extension-relay.js +101 -40
- package/dist/browser/pw-ai.js +1 -1
- package/dist/browser/pw-session.js +143 -8
- package/dist/browser/pw-tools-core.interactions.js +125 -27
- package/dist/browser/pw-tools-core.responses.js +1 -1
- package/dist/browser/pw-tools-core.state.js +1 -1
- package/dist/browser/routes/agent.act.js +86 -41
- package/dist/browser/routes/dispatcher.js +4 -4
- package/dist/browser/screenshot.js +1 -1
- package/dist/browser/server.js +13 -0
- package/dist/build-info.json +3 -3
- package/dist/canvas-host/a2ui/index.html +28 -28
- package/dist/channels/reply-prefix.js +8 -1
- package/dist/cli/cron-cli/register.cron-add.js +61 -40
- package/dist/cli/cron-cli/register.cron-edit.js +60 -34
- package/dist/cli/cron-cli/shared.js +56 -41
- package/dist/cli/dns-cli.js +26 -14
- package/dist/cli/gateway-cli/register.js +37 -19
- package/dist/cli/memory-cli.js +5 -5
- package/dist/cli/parse-bytes.js +37 -0
- package/dist/cli/update-cli.js +173 -52
- package/dist/commands/agent.js +1 -0
- package/dist/commands/auth-choice.apply.oauth.js +1 -1
- package/dist/commands/doctor-config-flow.js +61 -5
- package/dist/commands/doctor-state-migrations.js +1 -1
- package/dist/commands/health.js +1 -1
- package/dist/commands/model-allowlist.js +29 -0
- package/dist/commands/model-picker.js +2 -1
- package/dist/commands/models/list.registry.js +1 -1
- package/dist/commands/models/list.status-command.js +43 -23
- package/dist/commands/models/shared.js +15 -0
- package/dist/commands/onboard-custom.js +384 -0
- package/dist/commands/onboard-non-interactive/local/auth-choice-inference.js +35 -0
- package/dist/commands/onboard-non-interactive/local/auth-choice.js +6 -3
- package/dist/commands/onboard-skills.js +63 -38
- package/dist/commands/openai-model-default.js +41 -0
- package/dist/compat/legacy-names.js +2 -0
- package/dist/config/defaults.js +3 -2
- package/dist/config/paths.js +136 -35
- package/dist/config/plugin-auto-enable.js +21 -5
- package/dist/config/redact-snapshot.js +153 -0
- package/dist/config/schema.field-metadata.js +590 -0
- package/dist/config/schema.js +2 -2
- package/dist/config/sessions/store.js +291 -23
- package/dist/config/zod-schema.agent-defaults.js +3 -0
- package/dist/config/zod-schema.agent-runtime.js +13 -2
- package/dist/config/zod-schema.providers-core.js +142 -0
- package/dist/config/zod-schema.session.js +3 -0
- package/dist/control-ui/assets/{index-CIRDm-Lu.css → index-CSfXd2LO.css} +1 -1
- package/dist/control-ui/assets/{index-CmNMuoem.js → index-HRr1grwl.js} +446 -413
- package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -0
- package/dist/control-ui/index.html +4 -4
- package/dist/cron/delivery.js +57 -0
- package/dist/cron/isolated-agent/delivery-target.js +18 -3
- package/dist/cron/isolated-agent/helpers.js +22 -5
- package/dist/cron/isolated-agent/run.js +172 -63
- package/dist/cron/isolated-agent/session.js +2 -0
- package/dist/cron/normalize.js +356 -28
- package/dist/cron/parse.js +10 -5
- package/dist/cron/run-log.js +35 -10
- package/dist/cron/schedule.js +41 -6
- package/dist/cron/service/jobs.js +208 -35
- package/dist/cron/service/ops.js +72 -16
- package/dist/cron/service/state.js +2 -0
- package/dist/cron/service/store.js +386 -14
- package/dist/cron/service/timer.js +390 -147
- package/dist/cron/session-reaper.js +86 -0
- package/dist/cron/store.js +23 -8
- package/dist/cron/validate-timestamp.js +43 -0
- package/dist/discord/monitor/agent-components.js +438 -0
- package/dist/discord/monitor/allow-list.js +28 -5
- package/dist/discord/monitor/gateway-registry.js +29 -0
- package/dist/discord/monitor/native-command.js +44 -23
- package/dist/discord/monitor/sender-identity.js +45 -0
- package/dist/discord/pluralkit.js +27 -0
- package/dist/discord/send.outbound.js +92 -5
- package/dist/discord/send.shared.js +60 -23
- package/dist/discord/targets.js +84 -1
- package/dist/entry.js +15 -9
- package/dist/extensionAPI.js +8 -0
- package/dist/gateway/control-ui.js +8 -1
- package/dist/gateway/hooks-mapping.js +3 -0
- package/dist/gateway/hooks.js +65 -0
- package/dist/gateway/net.js +96 -31
- package/dist/gateway/node-command-policy.js +50 -15
- package/dist/gateway/origin-check.js +56 -0
- package/dist/gateway/protocol/client-info.js +9 -0
- package/dist/gateway/protocol/index.js +9 -2
- package/dist/gateway/protocol/schema/agents-models-skills.js +71 -1
- package/dist/gateway/protocol/schema/cron.js +22 -10
- package/dist/gateway/protocol/schema/protocol-schemas.js +16 -2
- package/dist/gateway/protocol/schema/sessions.js +12 -0
- package/dist/gateway/server/hooks.js +1 -1
- package/dist/gateway/server-broadcast.js +26 -9
- package/dist/gateway/server-chat.js +112 -23
- package/dist/gateway/server-discovery-runtime.js +10 -2
- package/dist/gateway/server-http.js +109 -11
- package/dist/gateway/server-methods/agent-timestamp.js +60 -0
- package/dist/gateway/server-methods/agents.js +321 -2
- package/dist/gateway/server-methods/usage.js +559 -16
- package/dist/gateway/server-runtime-state.js +22 -8
- package/dist/gateway/server-startup-memory.js +16 -0
- package/dist/gateway/server.impl.js +5 -1
- package/dist/gateway/session-utils.fs.js +23 -25
- package/dist/gateway/session-utils.js +20 -10
- package/dist/gateway/sessions-patch.js +7 -22
- package/dist/gateway/test-helpers.mocks.js +11 -7
- package/dist/gateway/test-helpers.server.js +35 -2
- package/dist/imessage/constants.js +2 -0
- package/dist/imessage/monitor/deliver.js +4 -1
- package/dist/imessage/monitor/monitor-provider.js +51 -1
- package/dist/infra/bonjour-discovery.js +131 -70
- package/dist/infra/control-ui-assets.js +134 -12
- package/dist/infra/errors.js +12 -0
- package/dist/infra/exec-approvals.js +266 -57
- package/dist/infra/format-time/format-datetime.js +79 -0
- package/dist/infra/format-time/format-duration.js +81 -0
- package/dist/infra/format-time/format-relative.js +80 -0
- package/dist/infra/heartbeat-runner.js +140 -49
- package/dist/infra/home-dir.js +54 -0
- package/dist/infra/net/fetch-guard.js +122 -0
- package/dist/infra/net/ssrf.js +65 -29
- package/dist/infra/outbound/abort.js +14 -0
- package/dist/infra/outbound/message-action-runner.js +77 -13
- package/dist/infra/outbound/outbound-session.js +143 -37
- package/dist/infra/poolbot-root.js +43 -1
- package/dist/infra/session-cost-usage.js +631 -41
- package/dist/infra/state-migrations.js +317 -47
- package/dist/infra/update-global.js +35 -0
- package/dist/infra/update-runner.js +149 -43
- package/dist/infra/warning-filter.js +65 -0
- package/dist/infra/widearea-dns.js +30 -9
- package/dist/logging/redact-identifier.js +12 -0
- package/dist/media/fetch.js +81 -58
- package/dist/media/store.js +2 -0
- package/dist/media-understanding/apply.js +403 -3
- package/dist/media-understanding/attachments.js +38 -27
- package/dist/media-understanding/defaults.js +16 -0
- package/dist/media-understanding/providers/deepgram/audio.js +22 -14
- package/dist/media-understanding/providers/google/audio.js +24 -17
- package/dist/media-understanding/providers/google/video.js +24 -17
- package/dist/media-understanding/providers/image.js +3 -3
- package/dist/media-understanding/providers/index.js +4 -1
- package/dist/media-understanding/providers/openai/audio.js +22 -14
- package/dist/media-understanding/providers/shared.js +16 -11
- package/dist/media-understanding/providers/zai/index.js +6 -0
- package/dist/media-understanding/runner.js +158 -90
- package/dist/memory/batch-voyage.js +277 -0
- package/dist/memory/embeddings-voyage.js +75 -0
- package/dist/memory/embeddings.js +28 -16
- package/dist/memory/internal.js +101 -18
- package/dist/memory/manager.js +154 -48
- package/dist/memory/search-manager.js +173 -0
- package/dist/memory/session-files.js +9 -3
- package/dist/node-host/runner.js +34 -24
- package/dist/node-host/with-timeout.js +27 -0
- package/dist/plugins/commands.js +5 -1
- package/dist/plugins/config-state.js +86 -7
- package/dist/plugins/source-display.js +51 -0
- package/dist/process/exec.js +20 -2
- package/dist/routing/resolve-route.js +12 -0
- package/dist/routing/session-key.js +15 -0
- package/dist/runtime.js +2 -0
- package/dist/security/audit-extra.async.js +601 -0
- package/dist/security/audit-extra.js +2 -830
- package/dist/security/audit-extra.sync.js +505 -0
- package/dist/security/channel-metadata.js +34 -0
- package/dist/security/external-content.js +88 -6
- package/dist/security/skill-scanner.js +330 -0
- package/dist/sessions/session-key-utils.js +7 -0
- package/dist/signal/monitor/event-handler.js +80 -1
- package/dist/slack/monitor/media.js +85 -15
- package/dist/tailscale/detect.js +1 -2
- package/dist/telegram/bot/helpers.js +109 -28
- package/dist/telegram/bot-handlers.js +144 -3
- package/dist/telegram/bot-message-context.js +37 -10
- package/dist/telegram/bot-message-dispatch.js +54 -17
- package/dist/telegram/bot-native-commands.js +86 -29
- package/dist/telegram/bot.js +30 -29
- package/dist/telegram/model-buttons.js +163 -0
- package/dist/telegram/monitor.js +110 -85
- package/dist/telegram/send.js +129 -47
- package/dist/terminal/restore.js +45 -0
- package/dist/test-helpers/state-dir-env.js +16 -0
- package/dist/tts/tts.js +12 -6
- package/dist/tui/tui-session-actions.js +166 -54
- package/dist/utils/fetch-timeout.js +20 -0
- package/dist/utils/normalize-secret-input.js +19 -0
- package/dist/utils/transcript-tools.js +58 -0
- package/dist/utils.js +45 -14
- package/dist/version.js +42 -5
- package/dist/wizard/clack-prompter.js +9 -6
- package/extensions/googlechat/node_modules/.bin/poolbot +21 -0
- package/extensions/googlechat/package.json +2 -2
- package/extensions/line/node_modules/.bin/poolbot +21 -0
- package/extensions/line/package.json +1 -1
- package/extensions/matrix/node_modules/.bin/poolbot +21 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/memory-core/node_modules/.bin/poolbot +21 -0
- package/extensions/memory-core/package.json +4 -1
- package/extensions/twitch/node_modules/.bin/poolbot +21 -0
- package/extensions/twitch/package.json +1 -1
- package/package.json +183 -24
- package/dist/control-ui/assets/index-CmNMuoem.js.map +0 -1
package/dist/telegram/monitor.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { run } from "@grammyjs/runner";
|
|
2
|
-
import { loadConfig } from "../config/config.js";
|
|
3
2
|
import { resolveAgentMaxConcurrent } from "../config/agent-limits.js";
|
|
3
|
+
import { loadConfig } from "../config/config.js";
|
|
4
4
|
import { computeBackoff, sleepWithAbort } from "../infra/backoff.js";
|
|
5
5
|
import { formatErrorMessage } from "../infra/errors.js";
|
|
6
|
-
import {
|
|
6
|
+
import { formatDurationPrecise } from "../infra/format-time/format-duration.js";
|
|
7
|
+
import { registerUnhandledRejectionHandler } from "../infra/unhandled-rejections.js";
|
|
7
8
|
import { resolveTelegramAccount } from "./accounts.js";
|
|
8
9
|
import { resolveTelegramAllowedUpdates } from "./allowed-updates.js";
|
|
9
10
|
import { createTelegramBot } from "./bot.js";
|
|
@@ -50,101 +51,125 @@ const isGetUpdatesConflict = (err) => {
|
|
|
50
51
|
.toLowerCase();
|
|
51
52
|
return haystack.includes("getupdates");
|
|
52
53
|
};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
accountId: opts.accountId,
|
|
58
|
-
});
|
|
59
|
-
const token = opts.token?.trim() || account.token;
|
|
60
|
-
if (!token) {
|
|
61
|
-
throw new Error(`Telegram bot token missing for account "${account.accountId}" (set channels.telegram.accounts.${account.accountId}.botToken/tokenFile or TELEGRAM_BOT_TOKEN for default).`);
|
|
54
|
+
/** Check if error is a Grammy HttpError (used to scope unhandled rejection handling) */
|
|
55
|
+
const isGrammyHttpError = (err) => {
|
|
56
|
+
if (!err || typeof err !== "object") {
|
|
57
|
+
return false;
|
|
62
58
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
updateId,
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
catch (err) {
|
|
79
|
-
(opts.runtime?.error ?? console.error)(`telegram: failed to persist update offset: ${String(err)}`);
|
|
59
|
+
return err.name === "HttpError";
|
|
60
|
+
};
|
|
61
|
+
export async function monitorTelegramProvider(opts = {}) {
|
|
62
|
+
const log = opts.runtime?.error ?? console.error;
|
|
63
|
+
// Register handler for Grammy HttpError unhandled rejections.
|
|
64
|
+
// This catches network errors that escape the polling loop's try-catch
|
|
65
|
+
// (e.g., from setMyCommands during bot setup).
|
|
66
|
+
// We gate on isGrammyHttpError to avoid suppressing non-Telegram errors.
|
|
67
|
+
const unregisterHandler = registerUnhandledRejectionHandler((err) => {
|
|
68
|
+
if (isGrammyHttpError(err) && isRecoverableTelegramNetworkError(err, { context: "polling" })) {
|
|
69
|
+
log(`[telegram] Suppressed network error: ${formatErrorMessage(err)}`);
|
|
70
|
+
return true; // handled - don't crash
|
|
80
71
|
}
|
|
81
|
-
|
|
82
|
-
const bot = createTelegramBot({
|
|
83
|
-
token,
|
|
84
|
-
runtime: opts.runtime,
|
|
85
|
-
proxyFetch,
|
|
86
|
-
config: cfg,
|
|
87
|
-
accountId: account.accountId,
|
|
88
|
-
updateOffset: {
|
|
89
|
-
lastUpdateId,
|
|
90
|
-
onUpdateId: persistUpdateId,
|
|
91
|
-
},
|
|
72
|
+
return false;
|
|
92
73
|
});
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
74
|
+
try {
|
|
75
|
+
const cfg = opts.config ?? loadConfig();
|
|
76
|
+
const account = resolveTelegramAccount({
|
|
77
|
+
cfg,
|
|
78
|
+
accountId: opts.accountId,
|
|
79
|
+
});
|
|
80
|
+
const token = opts.token?.trim() || account.token;
|
|
81
|
+
if (!token) {
|
|
82
|
+
throw new Error(`Telegram bot token missing for account "${account.accountId}" (set channels.telegram.accounts.${account.accountId}.botToken/tokenFile or TELEGRAM_BOT_TOKEN for default).`);
|
|
83
|
+
}
|
|
84
|
+
const proxyFetch = opts.proxyFetch ??
|
|
85
|
+
(account.config.proxy ? makeProxyFetch(account.config.proxy) : undefined);
|
|
86
|
+
let lastUpdateId = await readTelegramUpdateOffset({
|
|
96
87
|
accountId: account.accountId,
|
|
97
|
-
config: cfg,
|
|
98
|
-
path: opts.webhookPath,
|
|
99
|
-
port: opts.webhookPort,
|
|
100
|
-
secret: opts.webhookSecret,
|
|
101
|
-
runtime: opts.runtime,
|
|
102
|
-
fetch: proxyFetch,
|
|
103
|
-
abortSignal: opts.abortSignal,
|
|
104
|
-
publicUrl: opts.webhookUrl,
|
|
105
88
|
});
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
89
|
+
const persistUpdateId = async (updateId) => {
|
|
90
|
+
if (lastUpdateId !== null && updateId <= lastUpdateId)
|
|
91
|
+
return;
|
|
92
|
+
lastUpdateId = updateId;
|
|
93
|
+
try {
|
|
94
|
+
await writeTelegramUpdateOffset({
|
|
95
|
+
accountId: account.accountId,
|
|
96
|
+
updateId,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
(opts.runtime?.error ?? console.error)(`telegram: failed to persist update offset: ${String(err)}`);
|
|
115
101
|
}
|
|
116
102
|
};
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
103
|
+
const bot = createTelegramBot({
|
|
104
|
+
token,
|
|
105
|
+
runtime: opts.runtime,
|
|
106
|
+
proxyFetch,
|
|
107
|
+
config: cfg,
|
|
108
|
+
accountId: account.accountId,
|
|
109
|
+
updateOffset: {
|
|
110
|
+
lastUpdateId,
|
|
111
|
+
onUpdateId: persistUpdateId,
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
if (opts.useWebhook) {
|
|
115
|
+
await startTelegramWebhook({
|
|
116
|
+
token,
|
|
117
|
+
accountId: account.accountId,
|
|
118
|
+
config: cfg,
|
|
119
|
+
path: opts.webhookPath,
|
|
120
|
+
port: opts.webhookPort,
|
|
121
|
+
secret: opts.webhookSecret,
|
|
122
|
+
runtime: opts.runtime,
|
|
123
|
+
fetch: proxyFetch,
|
|
124
|
+
abortSignal: opts.abortSignal,
|
|
125
|
+
publicUrl: opts.webhookUrl,
|
|
126
|
+
});
|
|
121
127
|
return;
|
|
122
128
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const delayMs = computeBackoff(TELEGRAM_POLL_RESTART_POLICY, restartAttempts);
|
|
134
|
-
const reason = isConflict ? "getUpdates conflict" : "network error";
|
|
135
|
-
const errMsg = formatErrorMessage(err);
|
|
136
|
-
(opts.runtime?.error ?? console.error)(`Telegram ${reason}: ${errMsg}; retrying in ${formatDurationMs(delayMs)}.`);
|
|
129
|
+
// Use grammyjs/runner for concurrent update processing
|
|
130
|
+
let restartAttempts = 0;
|
|
131
|
+
while (!opts.abortSignal?.aborted) {
|
|
132
|
+
const runner = run(bot, createTelegramRunnerOptions(cfg));
|
|
133
|
+
const stopOnAbort = () => {
|
|
134
|
+
if (opts.abortSignal?.aborted) {
|
|
135
|
+
void runner.stop();
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
opts.abortSignal?.addEventListener("abort", stopOnAbort, { once: true });
|
|
137
139
|
try {
|
|
138
|
-
|
|
140
|
+
// runner.task() returns a promise that resolves when the runner stops
|
|
141
|
+
await runner.task();
|
|
142
|
+
return;
|
|
139
143
|
}
|
|
140
|
-
catch (
|
|
141
|
-
if (opts.abortSignal?.aborted)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
+
catch (err) {
|
|
145
|
+
if (opts.abortSignal?.aborted) {
|
|
146
|
+
throw err;
|
|
147
|
+
}
|
|
148
|
+
const isConflict = isGetUpdatesConflict(err);
|
|
149
|
+
const isRecoverable = isRecoverableTelegramNetworkError(err, { context: "polling" });
|
|
150
|
+
if (!isConflict && !isRecoverable) {
|
|
151
|
+
throw err;
|
|
152
|
+
}
|
|
153
|
+
restartAttempts += 1;
|
|
154
|
+
const delayMs = computeBackoff(TELEGRAM_POLL_RESTART_POLICY, restartAttempts);
|
|
155
|
+
const reason = isConflict ? "getUpdates conflict" : "network error";
|
|
156
|
+
const errMsg = formatErrorMessage(err);
|
|
157
|
+
(opts.runtime?.error ?? console.error)(`Telegram ${reason}: ${errMsg}; retrying in ${formatDurationPrecise(delayMs)}.`);
|
|
158
|
+
try {
|
|
159
|
+
await sleepWithAbort(delayMs, opts.abortSignal);
|
|
160
|
+
}
|
|
161
|
+
catch (sleepErr) {
|
|
162
|
+
if (opts.abortSignal?.aborted)
|
|
163
|
+
return;
|
|
164
|
+
throw sleepErr;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
finally {
|
|
168
|
+
opts.abortSignal?.removeEventListener("abort", stopOnAbort);
|
|
144
169
|
}
|
|
145
170
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
171
|
+
}
|
|
172
|
+
finally {
|
|
173
|
+
unregisterHandler();
|
|
149
174
|
}
|
|
150
175
|
}
|
package/dist/telegram/send.js
CHANGED
|
@@ -23,6 +23,7 @@ import { parseTelegramTarget, stripTelegramInternalPrefixes } from "./targets.js
|
|
|
23
23
|
import { resolveTelegramVoiceSend } from "./voice.js";
|
|
24
24
|
import { buildTelegramThreadParams } from "./bot/helpers.js";
|
|
25
25
|
const PARSE_ERR_RE = /can't parse entities|parse entities|find end of the entity/i;
|
|
26
|
+
const THREAD_NOT_FOUND_RE = /400:\s*Bad Request:\s*message thread not found/i;
|
|
26
27
|
const diagLogger = createSubsystemLogger("telegram/diagnostic");
|
|
27
28
|
function createTelegramHttpLogger(cfg) {
|
|
28
29
|
const enabled = isDiagnosticFlagEnabled("telegram.http", cfg);
|
|
@@ -101,6 +102,26 @@ function normalizeMessageId(raw) {
|
|
|
101
102
|
}
|
|
102
103
|
throw new Error("Message id is required for Telegram actions");
|
|
103
104
|
}
|
|
105
|
+
function isTelegramThreadNotFoundError(err) {
|
|
106
|
+
return THREAD_NOT_FOUND_RE.test(formatErrorMessage(err));
|
|
107
|
+
}
|
|
108
|
+
function hasMessageThreadIdParam(params) {
|
|
109
|
+
if (!params)
|
|
110
|
+
return false;
|
|
111
|
+
const value = params.message_thread_id;
|
|
112
|
+
if (typeof value === "number")
|
|
113
|
+
return Number.isFinite(value);
|
|
114
|
+
if (typeof value === "string")
|
|
115
|
+
return value.trim().length > 0;
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
function removeMessageThreadIdParam(params) {
|
|
119
|
+
if (!params || !hasMessageThreadIdParam(params))
|
|
120
|
+
return params;
|
|
121
|
+
const next = { ...params };
|
|
122
|
+
delete next.message_thread_id;
|
|
123
|
+
return Object.keys(next).length > 0 ? next : undefined;
|
|
124
|
+
}
|
|
104
125
|
export function buildInlineKeyboard(buttons) {
|
|
105
126
|
if (!buttons?.length)
|
|
106
127
|
return undefined;
|
|
@@ -136,8 +157,17 @@ export async function sendMessageTelegram(to, text, opts = {}) {
|
|
|
136
157
|
const messageThreadId = opts.messageThreadId != null ? opts.messageThreadId : target.messageThreadId;
|
|
137
158
|
const threadIdParams = buildTelegramThreadParams(messageThreadId);
|
|
138
159
|
const threadParams = threadIdParams ? { ...threadIdParams } : {};
|
|
160
|
+
const quoteText = opts.quoteText?.trim();
|
|
139
161
|
if (opts.replyToMessageId != null) {
|
|
140
|
-
|
|
162
|
+
if (quoteText) {
|
|
163
|
+
threadParams.reply_parameters = {
|
|
164
|
+
message_id: Math.trunc(opts.replyToMessageId),
|
|
165
|
+
quote: quoteText,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
threadParams.reply_to_message_id = Math.trunc(opts.replyToMessageId);
|
|
170
|
+
}
|
|
141
171
|
}
|
|
142
172
|
const hasThreadParams = Object.keys(threadParams).length > 0;
|
|
143
173
|
const request = createTelegramRetryRunner({
|
|
@@ -163,6 +193,21 @@ export async function sendMessageTelegram(to, text, opts = {}) {
|
|
|
163
193
|
`Input was: ${JSON.stringify(to)}.`,
|
|
164
194
|
].join(" "));
|
|
165
195
|
};
|
|
196
|
+
const sendWithThreadFallback = async (params, label, attempt) => {
|
|
197
|
+
try {
|
|
198
|
+
return await attempt(params, label);
|
|
199
|
+
}
|
|
200
|
+
catch (err) {
|
|
201
|
+
if (!hasMessageThreadIdParam(params) || !isTelegramThreadNotFoundError(err)) {
|
|
202
|
+
throw err;
|
|
203
|
+
}
|
|
204
|
+
if (opts.verbose) {
|
|
205
|
+
console.warn(`telegram ${label} failed with message_thread_id, retrying without thread: ${formatErrorMessage(err)}`);
|
|
206
|
+
}
|
|
207
|
+
const retriedParams = removeMessageThreadIdParam(params);
|
|
208
|
+
return await attempt(retriedParams, `${label}-threadless`);
|
|
209
|
+
}
|
|
210
|
+
};
|
|
166
211
|
const textMode = opts.textMode ?? "markdown";
|
|
167
212
|
const tableMode = resolveMarkdownTableMode({
|
|
168
213
|
cfg,
|
|
@@ -174,36 +219,40 @@ export async function sendMessageTelegram(to, text, opts = {}) {
|
|
|
174
219
|
const linkPreviewEnabled = account.config.linkPreview ?? true;
|
|
175
220
|
const linkPreviewOptions = linkPreviewEnabled ? undefined : { is_disabled: true };
|
|
176
221
|
const sendTelegramText = async (rawText, params, fallbackText) => {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const hasBaseParams = Object.keys(baseParams).length > 0;
|
|
183
|
-
const sendParams = {
|
|
184
|
-
parse_mode: "HTML",
|
|
185
|
-
...baseParams,
|
|
186
|
-
...(opts.silent === true ? { disable_notification: true } : {}),
|
|
187
|
-
};
|
|
188
|
-
const res = await requestWithDiag(() => api.sendMessage(chatId, htmlText, sendParams), "message").catch(async (err) => {
|
|
189
|
-
// Telegram rejects malformed HTML (e.g., unsupported tags or entities).
|
|
190
|
-
// When that happens, fall back to plain text so the message still delivers.
|
|
191
|
-
const errText = formatErrorMessage(err);
|
|
192
|
-
if (PARSE_ERR_RE.test(errText)) {
|
|
193
|
-
if (opts.verbose) {
|
|
194
|
-
console.warn(`telegram HTML parse failed, retrying as plain text: ${errText}`);
|
|
195
|
-
}
|
|
196
|
-
const fallback = fallbackText ?? rawText;
|
|
197
|
-
const plainParams = hasBaseParams ? baseParams : undefined;
|
|
198
|
-
return await requestWithDiag(() => plainParams
|
|
199
|
-
? api.sendMessage(chatId, fallback, plainParams)
|
|
200
|
-
: api.sendMessage(chatId, fallback), "message-plain").catch((err2) => {
|
|
201
|
-
throw wrapChatNotFound(err2);
|
|
202
|
-
});
|
|
222
|
+
return await sendWithThreadFallback(params, "message", async (effectiveParams, label) => {
|
|
223
|
+
const htmlText = renderHtmlText(rawText);
|
|
224
|
+
const baseParams = effectiveParams ? { ...effectiveParams } : {};
|
|
225
|
+
if (linkPreviewOptions) {
|
|
226
|
+
baseParams.link_preview_options = linkPreviewOptions;
|
|
203
227
|
}
|
|
204
|
-
|
|
228
|
+
const hasBaseParams = Object.keys(baseParams).length > 0;
|
|
229
|
+
const sendParams = {
|
|
230
|
+
parse_mode: "HTML",
|
|
231
|
+
...baseParams,
|
|
232
|
+
...(opts.silent === true ? { disable_notification: true } : {}),
|
|
233
|
+
};
|
|
234
|
+
const res = await requestWithDiag(() => api.sendMessage(chatId, htmlText, sendParams), label).catch(async (err) => {
|
|
235
|
+
// Telegram rejects malformed HTML (e.g., unsupported tags or entities).
|
|
236
|
+
// When that happens, fall back to plain text so the message still delivers.
|
|
237
|
+
const errText = formatErrorMessage(err);
|
|
238
|
+
if (PARSE_ERR_RE.test(errText)) {
|
|
239
|
+
if (opts.verbose) {
|
|
240
|
+
console.warn(`telegram HTML parse failed, retrying as plain text: ${errText}`);
|
|
241
|
+
}
|
|
242
|
+
const fallback = fallbackText ?? rawText;
|
|
243
|
+
const plainParams = hasBaseParams
|
|
244
|
+
? baseParams
|
|
245
|
+
: undefined;
|
|
246
|
+
return await requestWithDiag(() => plainParams
|
|
247
|
+
? api.sendMessage(chatId, fallback, plainParams)
|
|
248
|
+
: api.sendMessage(chatId, fallback), `${label}-plain`).catch((err2) => {
|
|
249
|
+
throw wrapChatNotFound(err2);
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
throw wrapChatNotFound(err);
|
|
253
|
+
});
|
|
254
|
+
return res;
|
|
205
255
|
});
|
|
206
|
-
return res;
|
|
207
256
|
};
|
|
208
257
|
if (mediaUrl) {
|
|
209
258
|
const media = await loadWebMedia(mediaUrl, opts.maxBytes);
|
|
@@ -212,9 +261,21 @@ export async function sendMessageTelegram(to, text, opts = {}) {
|
|
|
212
261
|
contentType: media.contentType,
|
|
213
262
|
fileName: media.fileName,
|
|
214
263
|
});
|
|
264
|
+
const isVideoNote = kind === "video" && opts.asVideoNote === true;
|
|
215
265
|
const fileName = media.fileName ?? (isGif ? "animation.gif" : inferFilename(kind)) ?? "file";
|
|
216
266
|
const file = new InputFile(media.buffer, fileName);
|
|
217
|
-
|
|
267
|
+
let caption;
|
|
268
|
+
let followUpText;
|
|
269
|
+
if (isVideoNote) {
|
|
270
|
+
// Video notes don't support captions; send any text as follow-up.
|
|
271
|
+
caption = undefined;
|
|
272
|
+
followUpText = text.trim() ? text : undefined;
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
const split = splitTelegramCaption(text);
|
|
276
|
+
caption = split.caption;
|
|
277
|
+
followUpText = split.followUpText;
|
|
278
|
+
}
|
|
218
279
|
const htmlCaption = caption ? renderHtmlText(caption) : undefined;
|
|
219
280
|
// If text exceeds Telegram's caption limit, send media without caption
|
|
220
281
|
// then send text as a separate follow-up message.
|
|
@@ -226,26 +287,32 @@ export async function sendMessageTelegram(to, text, opts = {}) {
|
|
|
226
287
|
...(!needsSeparateText && replyMarkup ? { reply_markup: replyMarkup } : {}),
|
|
227
288
|
};
|
|
228
289
|
const mediaParams = {
|
|
229
|
-
caption: htmlCaption,
|
|
230
|
-
...(htmlCaption ? { parse_mode: "HTML" } : {}),
|
|
290
|
+
...(htmlCaption ? { caption: htmlCaption, parse_mode: "HTML" } : {}),
|
|
231
291
|
...baseMediaParams,
|
|
232
292
|
...(opts.silent === true ? { disable_notification: true } : {}),
|
|
233
293
|
};
|
|
234
294
|
let result;
|
|
235
295
|
if (isGif) {
|
|
236
|
-
result = await requestWithDiag(() => api.sendAnimation(chatId, file,
|
|
296
|
+
result = await sendWithThreadFallback(mediaParams, "animation", async (effectiveParams, label) => requestWithDiag(() => api.sendAnimation(chatId, file, effectiveParams), label).catch((err) => {
|
|
237
297
|
throw wrapChatNotFound(err);
|
|
238
|
-
});
|
|
298
|
+
}));
|
|
239
299
|
}
|
|
240
300
|
else if (kind === "image") {
|
|
241
|
-
result = await requestWithDiag(() => api.sendPhoto(chatId, file,
|
|
301
|
+
result = await sendWithThreadFallback(mediaParams, "photo", async (effectiveParams, label) => requestWithDiag(() => api.sendPhoto(chatId, file, effectiveParams), label).catch((err) => {
|
|
242
302
|
throw wrapChatNotFound(err);
|
|
243
|
-
});
|
|
303
|
+
}));
|
|
244
304
|
}
|
|
245
305
|
else if (kind === "video") {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
306
|
+
if (isVideoNote) {
|
|
307
|
+
result = await sendWithThreadFallback(mediaParams, "video_note", async (effectiveParams, label) => requestWithDiag(() => api.sendVideoNote(chatId, file, effectiveParams), label).catch((err) => {
|
|
308
|
+
throw wrapChatNotFound(err);
|
|
309
|
+
}));
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
result = await sendWithThreadFallback(mediaParams, "video", async (effectiveParams, label) => requestWithDiag(() => api.sendVideo(chatId, file, effectiveParams), label).catch((err) => {
|
|
313
|
+
throw wrapChatNotFound(err);
|
|
314
|
+
}));
|
|
315
|
+
}
|
|
249
316
|
}
|
|
250
317
|
else if (kind === "audio") {
|
|
251
318
|
const { useVoice } = resolveTelegramVoiceSend({
|
|
@@ -255,20 +322,20 @@ export async function sendMessageTelegram(to, text, opts = {}) {
|
|
|
255
322
|
logFallback: logVerbose,
|
|
256
323
|
});
|
|
257
324
|
if (useVoice) {
|
|
258
|
-
result = await requestWithDiag(() => api.sendVoice(chatId, file,
|
|
325
|
+
result = await sendWithThreadFallback(mediaParams, "voice", async (effectiveParams, label) => requestWithDiag(() => api.sendVoice(chatId, file, effectiveParams), label).catch((err) => {
|
|
259
326
|
throw wrapChatNotFound(err);
|
|
260
|
-
});
|
|
327
|
+
}));
|
|
261
328
|
}
|
|
262
329
|
else {
|
|
263
|
-
result = await requestWithDiag(() => api.sendAudio(chatId, file,
|
|
330
|
+
result = await sendWithThreadFallback(mediaParams, "audio", async (effectiveParams, label) => requestWithDiag(() => api.sendAudio(chatId, file, effectiveParams), label).catch((err) => {
|
|
264
331
|
throw wrapChatNotFound(err);
|
|
265
|
-
});
|
|
332
|
+
}));
|
|
266
333
|
}
|
|
267
334
|
}
|
|
268
335
|
else {
|
|
269
|
-
result = await requestWithDiag(() => api.sendDocument(chatId, file,
|
|
336
|
+
result = await sendWithThreadFallback(mediaParams, "document", async (effectiveParams, label) => requestWithDiag(() => api.sendDocument(chatId, file, effectiveParams), label).catch((err) => {
|
|
270
337
|
throw wrapChatNotFound(err);
|
|
271
|
-
});
|
|
338
|
+
}));
|
|
272
339
|
}
|
|
273
340
|
const mediaMessageId = String(result?.message_id ?? "unknown");
|
|
274
341
|
const resolvedChatId = String(result?.chat?.id ?? chatId);
|
|
@@ -508,10 +575,25 @@ export async function sendStickerTelegram(to, fileId, opts = {}) {
|
|
|
508
575
|
`Input was: ${JSON.stringify(to)}.`,
|
|
509
576
|
].join(" "));
|
|
510
577
|
};
|
|
578
|
+
const sendWithStickerThreadFallback = async (params, label, attempt) => {
|
|
579
|
+
try {
|
|
580
|
+
return await attempt(params, label);
|
|
581
|
+
}
|
|
582
|
+
catch (err) {
|
|
583
|
+
if (!hasMessageThreadIdParam(params) || !isTelegramThreadNotFoundError(err)) {
|
|
584
|
+
throw err;
|
|
585
|
+
}
|
|
586
|
+
if (opts.verbose) {
|
|
587
|
+
console.warn(`telegram ${label} failed with message_thread_id, retrying without thread: ${formatErrorMessage(err)}`);
|
|
588
|
+
}
|
|
589
|
+
const retriedParams = removeMessageThreadIdParam(params);
|
|
590
|
+
return await attempt(retriedParams, `${label}-threadless`);
|
|
591
|
+
}
|
|
592
|
+
};
|
|
511
593
|
const stickerParams = hasThreadParams ? threadParams : undefined;
|
|
512
|
-
const result = await requestWithDiag(() => api.sendSticker(chatId, fileId.trim(),
|
|
594
|
+
const result = await sendWithStickerThreadFallback(stickerParams, "sticker", async (effectiveParams, label) => requestWithDiag(() => api.sendSticker(chatId, fileId.trim(), effectiveParams), label).catch((err) => {
|
|
513
595
|
throw wrapChatNotFound(err);
|
|
514
|
-
});
|
|
596
|
+
}));
|
|
515
597
|
const messageId = String(result?.message_id ?? "unknown");
|
|
516
598
|
const resolvedChatId = String(result?.chat?.id ?? chatId);
|
|
517
599
|
if (result?.message_id) {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { clearActiveProgressLine } from "./progress-line.js";
|
|
2
|
+
const RESET_SEQUENCE = "\x1b[0m\x1b[?25h\x1b[?1000l\x1b[?1002l\x1b[?1003l\x1b[?1006l\x1b[?2004l";
|
|
3
|
+
function reportRestoreFailure(scope, err, reason) {
|
|
4
|
+
const suffix = reason ? ` (${reason})` : "";
|
|
5
|
+
const message = `[terminal] restore ${scope} failed${suffix}: ${String(err)}`;
|
|
6
|
+
try {
|
|
7
|
+
process.stderr.write(`${message}\n`);
|
|
8
|
+
}
|
|
9
|
+
catch (writeErr) {
|
|
10
|
+
console.error(`[terminal] restore reporting failed${suffix}: ${String(writeErr)}`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export function restoreTerminalState(reason) {
|
|
14
|
+
try {
|
|
15
|
+
clearActiveProgressLine();
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
reportRestoreFailure("progress line", err, reason);
|
|
19
|
+
}
|
|
20
|
+
const stdin = process.stdin;
|
|
21
|
+
if (stdin.isTTY && typeof stdin.setRawMode === "function") {
|
|
22
|
+
try {
|
|
23
|
+
stdin.setRawMode(false);
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
reportRestoreFailure("raw mode", err, reason);
|
|
27
|
+
}
|
|
28
|
+
if (typeof stdin.isPaused === "function" && stdin.isPaused()) {
|
|
29
|
+
try {
|
|
30
|
+
stdin.resume();
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
reportRestoreFailure("stdin resume", err, reason);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (process.stdout.isTTY) {
|
|
38
|
+
try {
|
|
39
|
+
process.stdout.write(RESET_SEQUENCE);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
reportRestoreFailure("stdout reset", err, reason);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function snapshotStateDirEnv() {
|
|
2
|
+
return {
|
|
3
|
+
clawdbotStateDir: process.env.CLAWDBOT_STATE_DIR,
|
|
4
|
+
};
|
|
5
|
+
}
|
|
6
|
+
export function restoreStateDirEnv(snapshot) {
|
|
7
|
+
if (snapshot.clawdbotStateDir === undefined) {
|
|
8
|
+
delete process.env.CLAWDBOT_STATE_DIR;
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
process.env.CLAWDBOT_STATE_DIR = snapshot.clawdbotStateDir;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function setStateDirEnv(stateDir) {
|
|
15
|
+
process.env.CLAWDBOT_STATE_DIR = stateDir;
|
|
16
|
+
}
|
package/dist/tts/tts.js
CHANGED
|
@@ -579,9 +579,15 @@ export const OPENAI_TTS_MODELS = ["gpt-4o-mini-tts", "tts-1", "tts-1-hd"];
|
|
|
579
579
|
* Custom OpenAI-compatible TTS endpoint.
|
|
580
580
|
* When set, model/voice validation is relaxed to allow non-OpenAI models.
|
|
581
581
|
* Example: OPENAI_TTS_BASE_URL=http://localhost:8880/v1
|
|
582
|
+
*
|
|
583
|
+
* Note: Read at runtime (not module load) to support config.env loading.
|
|
582
584
|
*/
|
|
583
|
-
|
|
584
|
-
|
|
585
|
+
function getOpenAITtsBaseUrl() {
|
|
586
|
+
return (process.env.OPENAI_TTS_BASE_URL?.trim() || "https://api.openai.com/v1").replace(/\/+$/, "");
|
|
587
|
+
}
|
|
588
|
+
function isCustomOpenAIEndpoint() {
|
|
589
|
+
return getOpenAITtsBaseUrl() !== "https://api.openai.com/v1";
|
|
590
|
+
}
|
|
585
591
|
export const OPENAI_TTS_VOICES = [
|
|
586
592
|
"alloy",
|
|
587
593
|
"ash",
|
|
@@ -595,13 +601,13 @@ export const OPENAI_TTS_VOICES = [
|
|
|
595
601
|
];
|
|
596
602
|
function isValidOpenAIModel(model) {
|
|
597
603
|
// Allow any model when using custom endpoint (e.g., Kokoro, LocalAI)
|
|
598
|
-
if (isCustomOpenAIEndpoint)
|
|
604
|
+
if (isCustomOpenAIEndpoint())
|
|
599
605
|
return true;
|
|
600
606
|
return OPENAI_TTS_MODELS.includes(model);
|
|
601
607
|
}
|
|
602
608
|
function isValidOpenAIVoice(voice) {
|
|
603
609
|
// Allow any voice when using custom endpoint (e.g., Kokoro Chinese voices)
|
|
604
|
-
if (isCustomOpenAIEndpoint)
|
|
610
|
+
if (isCustomOpenAIEndpoint())
|
|
605
611
|
return true;
|
|
606
612
|
return OPENAI_TTS_VOICES.includes(voice);
|
|
607
613
|
}
|
|
@@ -679,7 +685,7 @@ async function summarizeText(params) {
|
|
|
679
685
|
catch (err) {
|
|
680
686
|
const error = err;
|
|
681
687
|
if (error.name === "AbortError") {
|
|
682
|
-
throw new Error("Summarization timed out");
|
|
688
|
+
throw new Error("Summarization timed out", { cause: err });
|
|
683
689
|
}
|
|
684
690
|
throw err;
|
|
685
691
|
}
|
|
@@ -754,7 +760,7 @@ async function openaiTTS(params) {
|
|
|
754
760
|
const controller = new AbortController();
|
|
755
761
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
756
762
|
try {
|
|
757
|
-
const response = await fetch(`${
|
|
763
|
+
const response = await fetch(`${getOpenAITtsBaseUrl()}/audio/speech`, {
|
|
758
764
|
method: "POST",
|
|
759
765
|
headers: {
|
|
760
766
|
Authorization: `Bearer ${apiKey}`,
|