@sulala/agent 0.1.6 → 0.1.7
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 +3 -2
- package/context/airtable.md +35 -0
- package/context/asana.md +37 -0
- package/context/bluesky.md +26 -91
- package/context/calendar.md +63 -0
- package/context/country-info.md +13 -0
- package/context/create-skill.md +128 -0
- package/context/discord.md +30 -0
- package/context/docs.md +29 -0
- package/context/drive.md +49 -0
- package/context/dropbox.md +39 -0
- package/context/facebook.md +47 -0
- package/context/fetch-form-api.md +16 -0
- package/context/figma.md +30 -0
- package/context/github.md +58 -0
- package/context/gmail.md +52 -0
- package/context/google.md +28 -0
- package/context/hellohub.md +29 -0
- package/context/jira.md +46 -0
- package/context/linear.md +40 -0
- package/context/notion.md +45 -0
- package/context/portal-integrations.md +42 -0
- package/context/post-to-x.md +50 -0
- package/context/sheets.md +47 -0
- package/context/slack.md +48 -0
- package/context/slides.md +35 -0
- package/context/stripe.md +38 -0
- package/context/tes.md +7 -0
- package/context/test.md +7 -0
- package/context/zoom.md +28 -0
- package/dist/agent/google/calendar.d.ts +2 -0
- package/dist/agent/google/calendar.d.ts.map +1 -0
- package/dist/agent/google/calendar.js +119 -0
- package/dist/agent/google/calendar.js.map +1 -0
- package/dist/agent/google/drive.d.ts +2 -0
- package/dist/agent/google/drive.d.ts.map +1 -0
- package/dist/agent/google/drive.js +51 -0
- package/dist/agent/google/drive.js.map +1 -0
- package/dist/agent/google/get-token.d.ts +7 -0
- package/dist/agent/google/get-token.d.ts.map +1 -0
- package/dist/agent/google/get-token.js +37 -0
- package/dist/agent/google/get-token.js.map +1 -0
- package/dist/agent/google/gmail.d.ts +2 -0
- package/dist/agent/google/gmail.d.ts.map +1 -0
- package/dist/agent/google/gmail.js +138 -0
- package/dist/agent/google/gmail.js.map +1 -0
- package/dist/agent/google/index.d.ts +2 -0
- package/dist/agent/google/index.d.ts.map +1 -0
- package/dist/agent/google/index.js +13 -0
- package/dist/agent/google/index.js.map +1 -0
- package/dist/agent/loop.d.ts +8 -0
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +226 -40
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/memory.d.ts +21 -0
- package/dist/agent/memory.d.ts.map +1 -0
- package/dist/agent/memory.js +33 -0
- package/dist/agent/memory.js.map +1 -0
- package/dist/agent/pending-actions.d.ts +21 -0
- package/dist/agent/pending-actions.d.ts.map +1 -0
- package/dist/agent/pending-actions.js +65 -0
- package/dist/agent/pending-actions.js.map +1 -0
- package/dist/agent/pi-runner.d.ts +27 -0
- package/dist/agent/pi-runner.d.ts.map +1 -0
- package/dist/agent/pi-runner.js +300 -0
- package/dist/agent/pi-runner.js.map +1 -0
- package/dist/agent/skill-generate.d.ts +63 -0
- package/dist/agent/skill-generate.d.ts.map +1 -0
- package/dist/agent/skill-generate.js +128 -0
- package/dist/agent/skill-generate.js.map +1 -0
- package/dist/agent/skill-install.d.ts.map +1 -1
- package/dist/agent/skill-install.js +80 -31
- package/dist/agent/skill-install.js.map +1 -1
- package/dist/agent/skill-templates.d.ts +17 -0
- package/dist/agent/skill-templates.d.ts.map +1 -0
- package/dist/agent/skill-templates.js +26 -0
- package/dist/agent/skill-templates.js.map +1 -0
- package/dist/agent/skills-config.d.ts +24 -2
- package/dist/agent/skills-config.d.ts.map +1 -1
- package/dist/agent/skills-config.js +107 -8
- package/dist/agent/skills-config.js.map +1 -1
- package/dist/agent/skills-watcher.js +1 -1
- package/dist/agent/skills.d.ts +9 -3
- package/dist/agent/skills.d.ts.map +1 -1
- package/dist/agent/skills.js +104 -9
- package/dist/agent/skills.js.map +1 -1
- package/dist/agent/tools.d.ts +25 -3
- package/dist/agent/tools.d.ts.map +1 -1
- package/dist/agent/tools.integrations.test.d.ts +2 -0
- package/dist/agent/tools.integrations.test.d.ts.map +1 -0
- package/dist/agent/tools.integrations.test.js +269 -0
- package/dist/agent/tools.integrations.test.js.map +1 -0
- package/dist/agent/tools.js +692 -39
- package/dist/agent/tools.js.map +1 -1
- package/dist/ai/orchestrator.d.ts +4 -1
- package/dist/ai/orchestrator.d.ts.map +1 -1
- package/dist/ai/orchestrator.js +246 -14
- package/dist/ai/orchestrator.js.map +1 -1
- package/dist/ai/pricing.d.ts +6 -0
- package/dist/ai/pricing.d.ts.map +1 -0
- package/dist/ai/pricing.js +39 -0
- package/dist/ai/pricing.js.map +1 -0
- package/dist/channels/discord.d.ts +15 -0
- package/dist/channels/discord.d.ts.map +1 -0
- package/dist/channels/discord.js +55 -0
- package/dist/channels/discord.js.map +1 -0
- package/dist/channels/stripe.d.ts +15 -0
- package/dist/channels/stripe.d.ts.map +1 -0
- package/dist/channels/stripe.js +58 -0
- package/dist/channels/stripe.js.map +1 -0
- package/dist/channels/telegram.d.ts +60 -0
- package/dist/channels/telegram.d.ts.map +1 -0
- package/dist/channels/telegram.js +562 -0
- package/dist/channels/telegram.js.map +1 -0
- package/dist/cli.js +66 -8
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +14 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +85 -1
- package/dist/config.js.map +1 -1
- package/dist/db/index.d.ts +83 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +174 -2
- package/dist/db/index.js.map +1 -1
- package/dist/db/schema.sql +35 -0
- package/dist/gateway/server.d.ts.map +1 -1
- package/dist/gateway/server.js +1219 -27
- package/dist/gateway/server.js.map +1 -1
- package/dist/index.js +149 -6
- package/dist/index.js.map +1 -1
- package/dist/ollama-setup.d.ts +27 -0
- package/dist/ollama-setup.d.ts.map +1 -0
- package/dist/ollama-setup.js +191 -0
- package/dist/ollama-setup.js.map +1 -0
- package/dist/onboard-env.d.ts +1 -1
- package/dist/onboard-env.d.ts.map +1 -1
- package/dist/onboard-env.js +2 -0
- package/dist/onboard-env.js.map +1 -1
- package/dist/onboard.d.ts +3 -1
- package/dist/onboard.d.ts.map +1 -1
- package/dist/onboard.js +7 -2
- package/dist/onboard.js.map +1 -1
- package/dist/plugins/index.d.ts +10 -0
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +32 -0
- package/dist/plugins/index.js.map +1 -1
- package/dist/redact.d.ts +15 -0
- package/dist/redact.d.ts.map +1 -0
- package/dist/redact.js +56 -0
- package/dist/redact.js.map +1 -0
- package/dist/scheduler/cron.d.ts +21 -0
- package/dist/scheduler/cron.d.ts.map +1 -1
- package/dist/scheduler/cron.js +60 -0
- package/dist/scheduler/cron.js.map +1 -1
- package/dist/system-capabilities.d.ts +11 -0
- package/dist/system-capabilities.d.ts.map +1 -0
- package/dist/system-capabilities.js +109 -0
- package/dist/system-capabilities.js.map +1 -0
- package/dist/types.d.ts +62 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/watcher/index.d.ts +2 -0
- package/dist/watcher/index.d.ts.map +1 -1
- package/dist/watcher/index.js +31 -1
- package/dist/watcher/index.js.map +1 -1
- package/dist/workspace-automations.d.ts +16 -0
- package/dist/workspace-automations.d.ts.map +1 -0
- package/dist/workspace-automations.js +133 -0
- package/dist/workspace-automations.js.map +1 -0
- package/package.json +19 -3
- package/registry/bluesky.md +12 -89
- package/registry/skills-registry.json +6 -0
- package/src/db/schema.sql +35 -0
- package/src/index.ts +159 -6
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telegram channel (OpenClaw-style): connect the Sulala agent to Telegram via a bot.
|
|
3
|
+
* Config can be set from env or from the dashboard (stored in DB); DB overrides env.
|
|
4
|
+
*/
|
|
5
|
+
import { Bot, InlineKeyboard } from 'grammy';
|
|
6
|
+
import { config } from '../config.js';
|
|
7
|
+
import { log, getChannelConfig, setChannelConfig, appendAgentMessage, updateAgentMessageToolResult } from '../db/index.js';
|
|
8
|
+
import { getOrCreateAgentSession } from '../db/index.js';
|
|
9
|
+
import { runAgentTurn, runAgentTurnStream } from '../agent/loop.js';
|
|
10
|
+
import { withSessionLock } from '../agent/session-queue.js';
|
|
11
|
+
import { executeTool } from '../agent/tools.js';
|
|
12
|
+
import { getPendingActionForReplay, getPendingAction, setPendingActionApproved, setPendingActionRejected, } from '../agent/pending-actions.js';
|
|
13
|
+
const TELEGRAM_MAX_MESSAGE_LENGTH = 4096;
|
|
14
|
+
const CHANNEL_KEY = 'telegram';
|
|
15
|
+
/** Throttle streaming edits to avoid Telegram rate limits. */
|
|
16
|
+
const STREAM_EDIT_THROTTLE_MS = 450;
|
|
17
|
+
/** Delay before auto-reconnecting after the bot stops or fails (e.g. 409 Conflict). */
|
|
18
|
+
const TELEGRAM_RECONNECT_DELAY_MS = 15000;
|
|
19
|
+
let telegramReconnectTimeout = null;
|
|
20
|
+
/** Pending approval per Telegram chat: chatId -> { pendingActionId, sessionId }. Cleared after approve/reject. */
|
|
21
|
+
const telegramPendingByChat = new Map();
|
|
22
|
+
/**
|
|
23
|
+
* Resolve provider and model for Telegram when not set in channel config.
|
|
24
|
+
* Prefers OpenRouter or OpenAI when the user has connected (API key set), instead of defaulting to Ollama.
|
|
25
|
+
*/
|
|
26
|
+
function resolveTelegramProviderAndModel(c) {
|
|
27
|
+
const provider = c.defaultProvider?.trim() ||
|
|
28
|
+
process.env.AI_DEFAULT_PROVIDER?.trim() ||
|
|
29
|
+
(process.env.OPENROUTER_API_KEY?.trim() ? 'openrouter' : null) ||
|
|
30
|
+
(process.env.OPENAI_API_KEY?.trim() ? 'openai' : null) ||
|
|
31
|
+
'ollama';
|
|
32
|
+
let model = c.defaultModel?.trim() || undefined;
|
|
33
|
+
if (!model) {
|
|
34
|
+
if (provider === 'ollama' || provider === 'llama')
|
|
35
|
+
model = process.env.AI_OLLAMA_DEFAULT_MODEL?.trim() || 'llama3.2';
|
|
36
|
+
else if (provider === 'openrouter')
|
|
37
|
+
model = process.env.AI_OPENROUTER_DEFAULT_MODEL?.trim() || 'openai/gpt-4o-mini';
|
|
38
|
+
else if (provider === 'openai')
|
|
39
|
+
model = process.env.AI_OPENAI_DEFAULT_MODEL?.trim() || 'gpt-4o-mini';
|
|
40
|
+
}
|
|
41
|
+
return { provider, model: model || undefined };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resolve default AI provider and model (env only, no channel config).
|
|
45
|
+
* Prefers OpenRouter or OpenAI when API keys are set, same as Telegram.
|
|
46
|
+
* Used for scheduled jobs when provider/model are not specified.
|
|
47
|
+
*/
|
|
48
|
+
export function resolveDefaultProviderAndModel(overrides) {
|
|
49
|
+
const provider = overrides?.provider?.trim() ||
|
|
50
|
+
process.env.AI_DEFAULT_PROVIDER?.trim() ||
|
|
51
|
+
(process.env.OPENROUTER_API_KEY?.trim() ? 'openrouter' : null) ||
|
|
52
|
+
(process.env.OPENAI_API_KEY?.trim() ? 'openai' : null) ||
|
|
53
|
+
'ollama';
|
|
54
|
+
let model = overrides?.model?.trim() || undefined;
|
|
55
|
+
if (!model) {
|
|
56
|
+
if (provider === 'ollama' || provider === 'llama')
|
|
57
|
+
model = process.env.AI_OLLAMA_DEFAULT_MODEL?.trim() || 'llama3.2';
|
|
58
|
+
else if (provider === 'openrouter')
|
|
59
|
+
model = process.env.AI_OPENROUTER_DEFAULT_MODEL?.trim() || 'openai/gpt-4o-mini';
|
|
60
|
+
else if (provider === 'openai')
|
|
61
|
+
model = process.env.AI_OPENAI_DEFAULT_MODEL?.trim() || 'gpt-4o-mini';
|
|
62
|
+
}
|
|
63
|
+
return { provider, model: model || undefined };
|
|
64
|
+
}
|
|
65
|
+
let currentBot = null;
|
|
66
|
+
let currentBotUsername = null;
|
|
67
|
+
/** Set when bot.start() fails (e.g. invalid token); cleared on successful start. */
|
|
68
|
+
let lastStartError = null;
|
|
69
|
+
function parseTelegramConfig(raw) {
|
|
70
|
+
if (!raw?.trim())
|
|
71
|
+
return null;
|
|
72
|
+
try {
|
|
73
|
+
const o = JSON.parse(raw);
|
|
74
|
+
const enabled = !!o.enabled;
|
|
75
|
+
const botToken = typeof o.botToken === 'string' ? o.botToken.trim() || null : null;
|
|
76
|
+
const dmPolicy = (o.dmPolicy === 'allowlist' || o.dmPolicy === 'disabled' ? o.dmPolicy : 'open');
|
|
77
|
+
const allowFrom = Array.isArray(o.allowFrom)
|
|
78
|
+
? o.allowFrom.map((x) => (typeof x === 'number' ? x : parseInt(String(x), 10))).filter((n) => !Number.isNaN(n))
|
|
79
|
+
: [];
|
|
80
|
+
const notificationChatId = typeof o.notificationChatId === 'number'
|
|
81
|
+
? o.notificationChatId
|
|
82
|
+
: typeof o.notificationChatId === 'string'
|
|
83
|
+
? parseInt(o.notificationChatId, 10)
|
|
84
|
+
: null;
|
|
85
|
+
const defaultProvider = typeof o.defaultProvider === 'string' ? o.defaultProvider.trim() || null : null;
|
|
86
|
+
const defaultModel = typeof o.defaultModel === 'string' ? o.defaultModel.trim() || null : null;
|
|
87
|
+
return {
|
|
88
|
+
enabled,
|
|
89
|
+
botToken,
|
|
90
|
+
dmPolicy,
|
|
91
|
+
allowFrom,
|
|
92
|
+
notificationChatId: typeof notificationChatId === 'number' && !Number.isNaN(notificationChatId) ? notificationChatId : null,
|
|
93
|
+
defaultProvider: defaultProvider ?? undefined,
|
|
94
|
+
defaultModel: defaultModel ?? undefined,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** Effective config: DB overrides env. */
|
|
102
|
+
export function getEffectiveTelegramConfig() {
|
|
103
|
+
const fromDb = parseTelegramConfig(getChannelConfig(CHANNEL_KEY));
|
|
104
|
+
if (fromDb)
|
|
105
|
+
return fromDb;
|
|
106
|
+
return {
|
|
107
|
+
enabled: config.telegram.enabled,
|
|
108
|
+
botToken: config.telegram.botToken,
|
|
109
|
+
dmPolicy: config.telegram.dmPolicy,
|
|
110
|
+
allowFrom: [...config.telegram.allowFrom],
|
|
111
|
+
notificationChatId: null,
|
|
112
|
+
defaultProvider: config.telegram.defaultProvider ?? undefined,
|
|
113
|
+
defaultModel: config.telegram.defaultModel ?? undefined,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/** State for API (no token). */
|
|
117
|
+
export function getTelegramChannelState() {
|
|
118
|
+
const c = getEffectiveTelegramConfig();
|
|
119
|
+
const configured = !!c.botToken?.trim();
|
|
120
|
+
let status = 'not_configured';
|
|
121
|
+
if (configured && (currentBotUsername || currentBot)) {
|
|
122
|
+
status = 'connected';
|
|
123
|
+
}
|
|
124
|
+
else if (configured && c.enabled && lastStartError) {
|
|
125
|
+
status = 'error';
|
|
126
|
+
}
|
|
127
|
+
else if (configured) {
|
|
128
|
+
status = 'not_configured';
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
enabled: c.enabled,
|
|
132
|
+
configured,
|
|
133
|
+
dmPolicy: c.dmPolicy,
|
|
134
|
+
allowFrom: c.allowFrom,
|
|
135
|
+
status,
|
|
136
|
+
botUsername: currentBotUsername ?? undefined,
|
|
137
|
+
error: lastStartError ?? undefined,
|
|
138
|
+
defaultProvider: c.defaultProvider ?? undefined,
|
|
139
|
+
defaultModel: c.defaultModel ?? undefined,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/** Save config to DB and restart the channel. */
|
|
143
|
+
export async function setTelegramChannelConfig(body) {
|
|
144
|
+
const c = getEffectiveTelegramConfig();
|
|
145
|
+
const enabled = body.enabled !== undefined ? body.enabled : c.enabled;
|
|
146
|
+
let botToken = body.botToken !== undefined ? (body.botToken?.trim() || null) : c.botToken;
|
|
147
|
+
const dmPolicy = body.dmPolicy ?? c.dmPolicy;
|
|
148
|
+
const allowFrom = body.allowFrom ?? c.allowFrom;
|
|
149
|
+
const notificationChatId = body.notificationChatId !== undefined ? body.notificationChatId : c.notificationChatId;
|
|
150
|
+
const defaultProvider = body.defaultProvider !== undefined ? (typeof body.defaultProvider === 'string' ? body.defaultProvider.trim() || null : null) : c.defaultProvider ?? null;
|
|
151
|
+
const defaultModel = body.defaultModel !== undefined ? (typeof body.defaultModel === 'string' ? body.defaultModel.trim() || null : null) : c.defaultModel ?? null;
|
|
152
|
+
if (typeof body.botToken === 'string' && body.botToken.trim() === '') {
|
|
153
|
+
botToken = null;
|
|
154
|
+
}
|
|
155
|
+
if (enabled && botToken) {
|
|
156
|
+
try {
|
|
157
|
+
const testBot = new Bot(botToken);
|
|
158
|
+
const me = await testBot.api.getMe();
|
|
159
|
+
if (!me?.username)
|
|
160
|
+
throw new Error('getMe returned no username');
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
164
|
+
return { ok: false, error: `Invalid bot token: ${msg}` };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const next = {
|
|
168
|
+
enabled,
|
|
169
|
+
botToken,
|
|
170
|
+
dmPolicy,
|
|
171
|
+
allowFrom,
|
|
172
|
+
notificationChatId: notificationChatId ?? null,
|
|
173
|
+
defaultProvider: defaultProvider ?? undefined,
|
|
174
|
+
defaultModel: defaultModel ?? undefined,
|
|
175
|
+
};
|
|
176
|
+
setChannelConfig(CHANNEL_KEY, JSON.stringify(next));
|
|
177
|
+
await restartTelegramChannel();
|
|
178
|
+
return { ok: true };
|
|
179
|
+
}
|
|
180
|
+
/** Send a notification message to the configured Telegram chat (job results, etc.). Returns true if sent. */
|
|
181
|
+
export async function sendTelegramNotification(text) {
|
|
182
|
+
const c = getEffectiveTelegramConfig();
|
|
183
|
+
const chatId = c.notificationChatId ?? null;
|
|
184
|
+
if (!currentBot || chatId === null)
|
|
185
|
+
return false;
|
|
186
|
+
const chunks = splitMessage(text);
|
|
187
|
+
try {
|
|
188
|
+
for (const chunk of chunks) {
|
|
189
|
+
await currentBot.api.sendMessage(chatId, chunk, { parse_mode: undefined });
|
|
190
|
+
}
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
log('telegram', 'error', err.message, { notificationChatId: chatId });
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
export async function stopTelegramChannel() {
|
|
199
|
+
if (telegramReconnectTimeout != null) {
|
|
200
|
+
clearTimeout(telegramReconnectTimeout);
|
|
201
|
+
telegramReconnectTimeout = null;
|
|
202
|
+
}
|
|
203
|
+
if (currentBot) {
|
|
204
|
+
const bot = currentBot;
|
|
205
|
+
currentBot = null;
|
|
206
|
+
currentBotUsername = null;
|
|
207
|
+
try {
|
|
208
|
+
await bot.stop();
|
|
209
|
+
}
|
|
210
|
+
catch (err) {
|
|
211
|
+
const code = err?.error_code;
|
|
212
|
+
if (code === 409) {
|
|
213
|
+
log('telegram', 'info', 'Telegram bot stop: 409 Conflict (another getUpdates in progress or another instance); ignoring.');
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
log('telegram', 'warn', 'Telegram bot stop error', { error: err.message });
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
export async function restartTelegramChannel() {
|
|
222
|
+
await stopTelegramChannel();
|
|
223
|
+
startTelegramChannel();
|
|
224
|
+
}
|
|
225
|
+
function canAcceptDm(userId, c) {
|
|
226
|
+
if (c.dmPolicy === 'disabled')
|
|
227
|
+
return false;
|
|
228
|
+
if (c.dmPolicy === 'open')
|
|
229
|
+
return true;
|
|
230
|
+
if (c.dmPolicy === 'allowlist')
|
|
231
|
+
return c.allowFrom.length > 0 && c.allowFrom.includes(userId);
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
const sessionKeyByChat = new Map();
|
|
235
|
+
function sessionKey(chatId, forceNew = false) {
|
|
236
|
+
if (!forceNew) {
|
|
237
|
+
const existing = sessionKeyByChat.get(chatId);
|
|
238
|
+
if (existing)
|
|
239
|
+
return existing;
|
|
240
|
+
}
|
|
241
|
+
const key = `telegram_${chatId}${forceNew ? `_${Date.now()}` : ''}`;
|
|
242
|
+
if (forceNew)
|
|
243
|
+
sessionKeyByChat.set(chatId, key);
|
|
244
|
+
return key;
|
|
245
|
+
}
|
|
246
|
+
function splitMessage(text) {
|
|
247
|
+
if (text.length <= TELEGRAM_MAX_MESSAGE_LENGTH)
|
|
248
|
+
return [text];
|
|
249
|
+
const chunks = [];
|
|
250
|
+
let rest = text;
|
|
251
|
+
while (rest.length > 0) {
|
|
252
|
+
if (rest.length <= TELEGRAM_MAX_MESSAGE_LENGTH) {
|
|
253
|
+
chunks.push(rest);
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
const slice = rest.slice(0, TELEGRAM_MAX_MESSAGE_LENGTH);
|
|
257
|
+
const lastNewline = slice.lastIndexOf('\n');
|
|
258
|
+
const breakAt = lastNewline > TELEGRAM_MAX_MESSAGE_LENGTH / 2 ? lastNewline + 1 : TELEGRAM_MAX_MESSAGE_LENGTH;
|
|
259
|
+
chunks.push(rest.slice(0, breakAt));
|
|
260
|
+
rest = rest.slice(breakAt);
|
|
261
|
+
}
|
|
262
|
+
return chunks;
|
|
263
|
+
}
|
|
264
|
+
export function startTelegramChannel() {
|
|
265
|
+
if (telegramReconnectTimeout != null) {
|
|
266
|
+
clearTimeout(telegramReconnectTimeout);
|
|
267
|
+
telegramReconnectTimeout = null;
|
|
268
|
+
}
|
|
269
|
+
const c = getEffectiveTelegramConfig();
|
|
270
|
+
if (!c.enabled || !c.botToken?.trim())
|
|
271
|
+
return;
|
|
272
|
+
const bot = new Bot(c.botToken);
|
|
273
|
+
currentBot = bot;
|
|
274
|
+
bot.command('start', async (ctx) => {
|
|
275
|
+
const fromId = ctx.from?.id;
|
|
276
|
+
if (ctx.chat?.type !== 'private')
|
|
277
|
+
return;
|
|
278
|
+
if (fromId !== undefined && !canAcceptDm(fromId, c)) {
|
|
279
|
+
await ctx.reply('This bot is not accepting DMs from you. Contact the bot admin to get access.');
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
await ctx.reply("Hi! I'm connected to Sulala Agent. Send me a message and I'll run the agent and reply. Commands: /new — new conversation, /status — session info.");
|
|
283
|
+
});
|
|
284
|
+
bot.command('new', async (ctx) => {
|
|
285
|
+
if (ctx.chat?.type !== 'private')
|
|
286
|
+
return;
|
|
287
|
+
const fromId = ctx.from?.id;
|
|
288
|
+
if (fromId !== undefined && !canAcceptDm(fromId, c))
|
|
289
|
+
return;
|
|
290
|
+
const key = sessionKey(ctx.chat.id, true);
|
|
291
|
+
const session = getOrCreateAgentSession(key, { telegram_chat_id: ctx.chat.id });
|
|
292
|
+
await ctx.reply(`Started a new conversation. Session: ${session.id.slice(0, 12)}…`);
|
|
293
|
+
});
|
|
294
|
+
bot.command('status', async (ctx) => {
|
|
295
|
+
if (ctx.chat?.type !== 'private')
|
|
296
|
+
return;
|
|
297
|
+
const fromId = ctx.from?.id;
|
|
298
|
+
if (fromId !== undefined && !canAcceptDm(fromId, c))
|
|
299
|
+
return;
|
|
300
|
+
const key = sessionKey(ctx.chat.id);
|
|
301
|
+
const session = getOrCreateAgentSession(key, { telegram_chat_id: ctx.chat.id });
|
|
302
|
+
await ctx.reply(`Session: ${session.id}\nKey: ${key}`);
|
|
303
|
+
});
|
|
304
|
+
bot.on('message:text', async (ctx) => {
|
|
305
|
+
const chatId = ctx.chat?.id;
|
|
306
|
+
const fromId = ctx.from?.id;
|
|
307
|
+
const text = ctx.message.text?.trim();
|
|
308
|
+
if (chatId === undefined || !text)
|
|
309
|
+
return;
|
|
310
|
+
const configNow = getEffectiveTelegramConfig();
|
|
311
|
+
if (ctx.chat.type === 'private') {
|
|
312
|
+
if (fromId !== undefined && !canAcceptDm(fromId, configNow)) {
|
|
313
|
+
await ctx.reply('This bot is not accepting DMs from you.');
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
const key = sessionKey(chatId);
|
|
318
|
+
const session = getOrCreateAgentSession(key, {
|
|
319
|
+
telegram_chat_id: chatId,
|
|
320
|
+
telegram_user_id: fromId,
|
|
321
|
+
telegram_username: ctx.from?.username ?? undefined,
|
|
322
|
+
});
|
|
323
|
+
// Use this chat for job notifications if none set yet
|
|
324
|
+
const cNow = getEffectiveTelegramConfig();
|
|
325
|
+
if (cNow.notificationChatId == null && ctx.chat?.id != null) {
|
|
326
|
+
setChannelConfig(CHANNEL_KEY, JSON.stringify({ ...cNow, notificationChatId: ctx.chat.id }));
|
|
327
|
+
}
|
|
328
|
+
try {
|
|
329
|
+
await ctx.api.sendChatAction(chatId, 'typing');
|
|
330
|
+
const { provider, model } = resolveTelegramProviderAndModel(cNow);
|
|
331
|
+
let streamMessageId = null;
|
|
332
|
+
let streamContent = '';
|
|
333
|
+
let throttleTimer = null;
|
|
334
|
+
const doStreamEdit = () => {
|
|
335
|
+
if (streamMessageId == null)
|
|
336
|
+
return;
|
|
337
|
+
const toShow = streamContent.length <= TELEGRAM_MAX_MESSAGE_LENGTH
|
|
338
|
+
? streamContent || '…'
|
|
339
|
+
: '…\n' + streamContent.slice(-(TELEGRAM_MAX_MESSAGE_LENGTH - 2));
|
|
340
|
+
ctx.api.editMessageText(chatId, streamMessageId, toShow).catch(() => { });
|
|
341
|
+
};
|
|
342
|
+
const sent = await ctx.reply('…', { parse_mode: undefined });
|
|
343
|
+
streamMessageId = sent.message_id;
|
|
344
|
+
const result = await withSessionLock(session.id, () => runAgentTurnStream({
|
|
345
|
+
sessionId: session.id,
|
|
346
|
+
userMessage: text,
|
|
347
|
+
provider: provider || undefined,
|
|
348
|
+
model: model || undefined,
|
|
349
|
+
}, (ev) => {
|
|
350
|
+
if (ev.type === 'assistant') {
|
|
351
|
+
streamContent += ev.delta;
|
|
352
|
+
if (throttleTimer == null) {
|
|
353
|
+
throttleTimer = setTimeout(() => {
|
|
354
|
+
throttleTimer = null;
|
|
355
|
+
doStreamEdit();
|
|
356
|
+
}, STREAM_EDIT_THROTTLE_MS);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
if (ev.type === 'thinking') {
|
|
360
|
+
streamContent += ev.delta;
|
|
361
|
+
if (throttleTimer == null) {
|
|
362
|
+
throttleTimer = setTimeout(() => {
|
|
363
|
+
throttleTimer = null;
|
|
364
|
+
doStreamEdit();
|
|
365
|
+
}, STREAM_EDIT_THROTTLE_MS);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (ev.type === 'tool_call') {
|
|
369
|
+
if (throttleTimer != null) {
|
|
370
|
+
clearTimeout(throttleTimer);
|
|
371
|
+
throttleTimer = null;
|
|
372
|
+
}
|
|
373
|
+
streamContent += `\n\n(Running ${ev.name}…)`;
|
|
374
|
+
doStreamEdit();
|
|
375
|
+
}
|
|
376
|
+
if (ev.type === 'error') {
|
|
377
|
+
if (throttleTimer != null) {
|
|
378
|
+
clearTimeout(throttleTimer);
|
|
379
|
+
throttleTimer = null;
|
|
380
|
+
}
|
|
381
|
+
if (streamMessageId != null) {
|
|
382
|
+
ctx.api.editMessageText(chatId, streamMessageId, `Error: ${ev.message.slice(0, 500)}`).catch(() => { });
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}));
|
|
386
|
+
if (throttleTimer != null) {
|
|
387
|
+
clearTimeout(throttleTimer);
|
|
388
|
+
throttleTimer = null;
|
|
389
|
+
}
|
|
390
|
+
const reply = result.finalContent?.trim() || '';
|
|
391
|
+
const hasMeaningfulReply = reply.length > 0 && reply !== '(No response.)';
|
|
392
|
+
if (streamMessageId != null) {
|
|
393
|
+
const finalText = result.pendingActionId && !hasMeaningfulReply
|
|
394
|
+
? 'The agent is waiting to perform an action. Approve or reject below.'
|
|
395
|
+
: reply || '(No response.)';
|
|
396
|
+
const chunks = splitMessage(finalText);
|
|
397
|
+
await ctx.api.editMessageText(chatId, streamMessageId, chunks[0] || '…').catch(() => { });
|
|
398
|
+
for (let i = 1; i < chunks.length; i++) {
|
|
399
|
+
await ctx.api.sendMessage(chatId, chunks[i], { parse_mode: undefined });
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
if (result.pendingActionId) {
|
|
403
|
+
telegramPendingByChat.set(chatId, { pendingActionId: result.pendingActionId, sessionId: session.id });
|
|
404
|
+
const keyboard = new InlineKeyboard()
|
|
405
|
+
.text('✅ Approve', `approve:${result.pendingActionId}`)
|
|
406
|
+
.text('❌ Reject', `reject:${result.pendingActionId}`);
|
|
407
|
+
const approvalText = hasMeaningfulReply
|
|
408
|
+
? 'Approve or reject this action:'
|
|
409
|
+
: 'Approve or reject:';
|
|
410
|
+
await ctx.reply(approvalText, { reply_markup: keyboard });
|
|
411
|
+
}
|
|
412
|
+
else if (!hasMeaningfulReply && streamMessageId == null) {
|
|
413
|
+
await ctx.reply('(No response.)', { parse_mode: undefined });
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
catch (err) {
|
|
417
|
+
const message = err.message;
|
|
418
|
+
log('telegram', 'error', message, { chatId, sessionId: session.id });
|
|
419
|
+
await ctx.reply(`Error: ${message.slice(0, 500)}`);
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
bot.on('callback_query', async (ctx) => {
|
|
423
|
+
const data = ctx.callbackQuery?.data;
|
|
424
|
+
const chatId = ctx.callbackQuery?.message?.chat?.id;
|
|
425
|
+
if (!data || chatId === undefined) {
|
|
426
|
+
await ctx.answerCallbackQuery().catch(() => { });
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
const isApprove = data.startsWith('approve:');
|
|
430
|
+
const isReject = data.startsWith('reject:');
|
|
431
|
+
if (!isApprove && !isReject) {
|
|
432
|
+
await ctx.answerCallbackQuery().catch(() => { });
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
const actionId = data.slice(isApprove ? 8 : 7);
|
|
436
|
+
const pending = telegramPendingByChat.get(chatId);
|
|
437
|
+
if (!pending || pending.pendingActionId !== actionId) {
|
|
438
|
+
await ctx.answerCallbackQuery({ text: 'This approval has expired or was already handled.' }).catch(() => { });
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
telegramPendingByChat.delete(chatId);
|
|
442
|
+
await ctx.answerCallbackQuery().catch(() => { });
|
|
443
|
+
const cNow = getEffectiveTelegramConfig();
|
|
444
|
+
const { provider, model } = resolveTelegramProviderAndModel(cNow);
|
|
445
|
+
if (isApprove) {
|
|
446
|
+
const forReplay = getPendingActionForReplay(actionId);
|
|
447
|
+
if (!forReplay) {
|
|
448
|
+
await ctx.reply('This action was already handled or has expired.');
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
let result;
|
|
452
|
+
try {
|
|
453
|
+
result = await executeTool(forReplay.toolName, forReplay.args, {
|
|
454
|
+
sessionId: forReplay.sessionId,
|
|
455
|
+
toolCallId: forReplay.toolCallId,
|
|
456
|
+
skipApproval: true,
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
catch (err) {
|
|
460
|
+
result = { error: err instanceof Error ? err.message : String(err) };
|
|
461
|
+
}
|
|
462
|
+
const resultContent = typeof result === 'string' ? result : JSON.stringify(result);
|
|
463
|
+
const updated = updateAgentMessageToolResult(forReplay.sessionId, forReplay.toolCallId, resultContent);
|
|
464
|
+
if (!updated) {
|
|
465
|
+
appendAgentMessage({
|
|
466
|
+
session_id: forReplay.sessionId,
|
|
467
|
+
role: 'tool',
|
|
468
|
+
tool_call_id: forReplay.toolCallId,
|
|
469
|
+
name: forReplay.toolName,
|
|
470
|
+
content: resultContent,
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
setPendingActionApproved(actionId, result);
|
|
474
|
+
const continueResult = await withSessionLock(forReplay.sessionId, () => runAgentTurn({
|
|
475
|
+
sessionId: forReplay.sessionId,
|
|
476
|
+
userMessage: null,
|
|
477
|
+
provider: provider || undefined,
|
|
478
|
+
model: model || undefined,
|
|
479
|
+
}));
|
|
480
|
+
const reply = continueResult.finalContent?.trim() || '(Done.)';
|
|
481
|
+
const chunks = splitMessage(reply);
|
|
482
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
483
|
+
await ctx.api.sendMessage(chatId, chunks[i], { parse_mode: undefined });
|
|
484
|
+
}
|
|
485
|
+
if (continueResult.pendingActionId) {
|
|
486
|
+
telegramPendingByChat.set(chatId, { pendingActionId: continueResult.pendingActionId, sessionId: forReplay.sessionId });
|
|
487
|
+
const keyboard = new InlineKeyboard()
|
|
488
|
+
.text('✅ Approve', `approve:${continueResult.pendingActionId}`)
|
|
489
|
+
.text('❌ Reject', `reject:${continueResult.pendingActionId}`);
|
|
490
|
+
await ctx.api.sendMessage(chatId, 'This action needs your approval. Approve or reject:', { reply_markup: keyboard });
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
else {
|
|
494
|
+
const pendingAction = getPendingAction(actionId);
|
|
495
|
+
if (!pendingAction || pendingAction.status !== 'pending') {
|
|
496
|
+
await ctx.reply('This action was already handled or has expired.');
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
setPendingActionRejected(actionId);
|
|
500
|
+
const rejectedContent = JSON.stringify({ error: 'User rejected this action.' });
|
|
501
|
+
const updated = updateAgentMessageToolResult(pendingAction.sessionId, pendingAction.toolCallId, rejectedContent);
|
|
502
|
+
if (!updated) {
|
|
503
|
+
appendAgentMessage({
|
|
504
|
+
session_id: pendingAction.sessionId,
|
|
505
|
+
role: 'tool',
|
|
506
|
+
tool_call_id: pendingAction.toolCallId,
|
|
507
|
+
name: pendingAction.toolName,
|
|
508
|
+
content: rejectedContent,
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
const continueResult = await withSessionLock(pendingAction.sessionId, () => runAgentTurn({
|
|
512
|
+
sessionId: pendingAction.sessionId,
|
|
513
|
+
userMessage: null,
|
|
514
|
+
provider: provider || undefined,
|
|
515
|
+
model: model || undefined,
|
|
516
|
+
}));
|
|
517
|
+
const reply = continueResult.finalContent?.trim() || 'Action rejected.';
|
|
518
|
+
const chunks = splitMessage(reply);
|
|
519
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
520
|
+
await ctx.api.sendMessage(chatId, chunks[i], { parse_mode: undefined });
|
|
521
|
+
}
|
|
522
|
+
if (continueResult.pendingActionId) {
|
|
523
|
+
telegramPendingByChat.set(chatId, { pendingActionId: continueResult.pendingActionId, sessionId: pendingAction.sessionId });
|
|
524
|
+
const keyboard = new InlineKeyboard()
|
|
525
|
+
.text('✅ Approve', `approve:${continueResult.pendingActionId}`)
|
|
526
|
+
.text('❌ Reject', `reject:${continueResult.pendingActionId}`);
|
|
527
|
+
await ctx.api.sendMessage(chatId, 'This action needs your approval. Approve or reject:', { reply_markup: keyboard });
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
bot.catch((err) => {
|
|
532
|
+
const msg = err.error instanceof Error ? err.error.message : String(err.error ?? err);
|
|
533
|
+
log('telegram', 'error', msg, {});
|
|
534
|
+
});
|
|
535
|
+
lastStartError = null;
|
|
536
|
+
bot
|
|
537
|
+
.start({
|
|
538
|
+
onStart: (info) => {
|
|
539
|
+
currentBotUsername = info.username ?? null;
|
|
540
|
+
lastStartError = null;
|
|
541
|
+
log('telegram', 'info', 'Telegram bot started', { username: info.username });
|
|
542
|
+
},
|
|
543
|
+
})
|
|
544
|
+
.catch((err) => {
|
|
545
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
546
|
+
lastStartError = msg;
|
|
547
|
+
log('telegram', 'warn', 'Telegram channel failed to start', { error: msg });
|
|
548
|
+
currentBot = null;
|
|
549
|
+
currentBotUsername = null;
|
|
550
|
+
if (telegramReconnectTimeout)
|
|
551
|
+
return;
|
|
552
|
+
const c = getEffectiveTelegramConfig();
|
|
553
|
+
if (!c.enabled || !c.botToken?.trim())
|
|
554
|
+
return;
|
|
555
|
+
log('telegram', 'info', `Auto-reconnecting in ${TELEGRAM_RECONNECT_DELAY_MS / 1000}s…`);
|
|
556
|
+
telegramReconnectTimeout = setTimeout(() => {
|
|
557
|
+
telegramReconnectTimeout = null;
|
|
558
|
+
startTelegramChannel();
|
|
559
|
+
}, TELEGRAM_RECONNECT_DELAY_MS);
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
//# sourceMappingURL=telegram.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../src/channels/telegram.ts"],"names":[],"mappings":"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"}
|