talon-agent 4.3.2 → 4.4.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/package.json +1 -1
- package/src/app.ts +1 -1
- package/src/backend/claude-sdk/doctor.ts +1 -1
- package/src/backend/claude-sdk/state.ts +1 -1
- package/src/backend/codex/doctor.ts +1 -1
- package/src/backend/codex/init.ts +1 -1
- package/src/backend/codex/state.ts +1 -1
- package/src/backend/openai-agents/doctor.ts +1 -1
- package/src/backend/openai-agents/init.ts +1 -1
- package/src/backend/openai-agents/state.ts +1 -1
- package/src/backend/remote-server/factory.ts +1 -1
- package/src/backend/remote-server/mcp.ts +1 -1
- package/src/backend/remote-server/server-bindings.ts +1 -1
- package/src/backend/remote-server/state.ts +1 -1
- package/src/backend/shared/system-prompt.ts +1 -1
- package/src/bootstrap.ts +3 -3
- package/src/cli/chat.ts +1 -1
- package/src/cli/config.ts +2 -2
- package/src/cli/doctor.ts +1 -1
- package/src/cli/index.ts +8 -0
- package/src/cli/memory.ts +166 -0
- package/src/cli/setup.ts +1 -1
- package/src/core/agent-runtime/backend-registry.ts +2 -2
- package/src/core/agent-runtime/model-ref.ts +2 -2
- package/src/core/auth/expiry-monitor.ts +1 -1
- package/src/{util/config.ts → core/config/index.ts} +8 -8
- package/src/core/{doctor.ts → doctor/index.ts} +11 -11
- package/src/core/engine/backend-controller/legacy.ts +1 -1
- package/src/core/engine/backend-controller/pool.ts +1 -1
- package/src/core/engine/backend-controller/rebind.ts +1 -1
- package/src/core/engine/backend-controller/state.ts +1 -1
- package/src/core/engine/gateway-actions/plugins.ts +1 -1
- package/src/core/engine/model-audit.ts +1 -1
- package/src/core/{notify.ts → frontend-runtime/admin-notify.ts} +1 -1
- package/src/core/frontend-runtime/capabilities.ts +1 -1
- package/src/core/models/active-model.ts +1 -1
- package/src/core/plugin/builtins.ts +2 -2
- package/src/core/plugin/manage.ts +1 -1
- package/src/core/plugin/native-runtimes.ts +1 -1
- package/src/frontend/discord/admin.ts +1 -1
- package/src/frontend/discord/callbacks/components/index.ts +1 -1
- package/src/frontend/discord/callbacks/components/settings.ts +1 -1
- package/src/frontend/discord/callbacks/components/types.ts +1 -1
- package/src/frontend/discord/callbacks/modals.ts +1 -1
- package/src/frontend/discord/commands/admin.ts +2 -2
- package/src/frontend/discord/commands/definitions.ts +1 -1
- package/src/frontend/discord/commands/info.ts +1 -1
- package/src/frontend/discord/commands/router.ts +1 -1
- package/src/frontend/discord/commands/session.ts +1 -1
- package/src/frontend/discord/commands/settings.ts +1 -1
- package/src/frontend/discord/handlers/delivery.ts +1 -1
- package/src/frontend/discord/handlers/messages.ts +1 -1
- package/src/frontend/discord/handlers/queue.ts +1 -1
- package/src/frontend/discord/handlers/state.ts +1 -1
- package/src/frontend/discord/index.ts +1 -1
- package/src/frontend/discord/middleware.ts +1 -1
- package/src/frontend/discord/render.ts +1 -1
- package/src/frontend/discord/runtime.ts +1 -1
- package/src/frontend/native/extensions.ts +4 -1
- package/src/frontend/native/index.ts +1 -1
- package/src/frontend/native/runtime.ts +1 -1
- package/src/frontend/native/settings.ts +1 -1
- package/src/frontend/shared/model-commands.ts +1 -1
- package/src/frontend/shared/plan-usage-report.ts +1 -1
- package/src/frontend/shared/reasoning-levels.ts +1 -1
- package/src/frontend/shared/session-status.ts +1 -1
- package/src/frontend/teams/index.ts +1 -1
- package/src/frontend/teams/runtime.ts +1 -1
- package/src/frontend/telegram/actions/chat-info.ts +1 -1
- package/src/frontend/telegram/actions/coerce.ts +15 -0
- package/src/frontend/telegram/actions/index.ts +2 -2
- package/src/frontend/telegram/actions/media.ts +1 -1
- package/src/frontend/telegram/actions/messaging.ts +3 -4
- package/src/frontend/telegram/actions/moderation/chat.ts +63 -0
- package/src/frontend/telegram/actions/moderation/index.ts +74 -0
- package/src/frontend/telegram/actions/moderation/members.ts +77 -0
- package/src/frontend/telegram/actions/moderation/permissions.ts +69 -0
- package/src/frontend/telegram/actions/moderation/topics.ts +48 -0
- package/src/frontend/telegram/actions/moderation/types.ts +16 -0
- package/src/frontend/telegram/actions/rich-messages.ts +51 -0
- package/src/frontend/telegram/actions/{shared.ts → send.ts} +9 -59
- package/src/frontend/telegram/admin/background.ts +66 -0
- package/src/frontend/telegram/admin/chunked-reply.ts +20 -0
- package/src/frontend/telegram/admin/health.ts +81 -0
- package/src/frontend/telegram/admin/sessions.ts +105 -0
- package/src/frontend/telegram/admin.ts +57 -262
- package/src/frontend/telegram/callbacks/auth.ts +1 -1
- package/src/frontend/telegram/callbacks/effort.ts +1 -1
- package/src/frontend/telegram/callbacks/index.ts +3 -3
- package/src/frontend/telegram/callbacks/metrics.ts +1 -1
- package/src/frontend/telegram/callbacks/model/backend.ts +156 -0
- package/src/frontend/telegram/callbacks/model/control.ts +29 -0
- package/src/frontend/telegram/callbacks/model/nav.ts +54 -0
- package/src/frontend/telegram/callbacks/model/select.ts +100 -0
- package/src/frontend/telegram/callbacks/model/types.ts +39 -0
- package/src/frontend/telegram/callbacks/model/views.ts +116 -0
- package/src/frontend/telegram/callbacks/model.ts +61 -331
- package/src/frontend/telegram/callbacks/pulse.ts +1 -1
- package/src/frontend/telegram/callbacks/{shared.ts → query.ts} +3 -2
- package/src/frontend/telegram/callbacks/settings.ts +1 -1
- package/src/frontend/telegram/callbacks/whatsapp.ts +1 -1
- package/src/frontend/telegram/commands/admin.ts +108 -77
- package/src/frontend/telegram/commands/index.ts +1 -1
- package/src/frontend/telegram/commands/settings.ts +65 -43
- package/src/frontend/telegram/commands/state.ts +1 -1
- package/src/frontend/telegram/commands/whatsapp-pairing.ts +1 -1
- package/src/frontend/telegram/handlers/context.ts +1 -1
- package/src/frontend/telegram/handlers/delivery.ts +2 -2
- package/src/frontend/telegram/handlers/messages.ts +1 -1
- package/src/frontend/telegram/handlers/queue.ts +1 -1
- package/src/frontend/telegram/handlers/state.ts +1 -1
- package/src/frontend/telegram/helpers/diagnostics.ts +1 -1
- package/src/frontend/telegram/index.ts +1 -1
- package/src/frontend/telegram/middleware.ts +167 -202
- package/src/frontend/telegram/model-menu.ts +1 -1
- package/src/frontend/terminal/builtins/context.ts +184 -0
- package/src/frontend/terminal/builtins/help.ts +35 -0
- package/src/frontend/terminal/builtins/index.ts +23 -0
- package/src/frontend/terminal/builtins/model.ts +198 -0
- package/src/frontend/terminal/builtins/session.ts +101 -0
- package/src/frontend/terminal/builtins/status.ts +202 -0
- package/src/frontend/terminal/command-registry.ts +80 -0
- package/src/frontend/terminal/commands.ts +11 -674
- package/src/frontend/terminal/index.ts +1 -1
- package/src/frontend/terminal/input/history.ts +64 -0
- package/src/frontend/terminal/input/keys.ts +143 -0
- package/src/frontend/terminal/input/parts.ts +33 -0
- package/src/frontend/terminal/input/paste.ts +53 -0
- package/src/frontend/terminal/input/render.ts +42 -0
- package/src/frontend/terminal/input/state.ts +60 -0
- package/src/frontend/terminal/input.ts +27 -342
- package/src/frontend/whatsapp/connection.ts +1 -1
- package/src/frontend/whatsapp/index.ts +2 -2
- package/src/frontend/whatsapp/pairing-service.ts +1 -1
- package/src/frontend/whatsapp/runtime.ts +1 -1
- package/src/plugins/github/provision.ts +1 -1
- package/src/plugins/mempalace/provision.ts +1 -1
- package/src/plugins/playwright/provision.ts +1 -1
- package/src/storage/memory.ts +505 -0
- package/src/storage/repositories/memory-repo.ts +308 -0
- package/src/storage/sql/memory.sql +95 -0
- package/src/storage/sql/schema.sql +81 -0
- package/src/storage/sql/statements.generated.ts +146 -0
- package/src/frontend/telegram/actions/moderation.ts +0 -255
- /package/src/core/{doctor-types.ts → doctor/types.ts} +0 -0
- /package/src/core/{pairing-broker.ts → frontend-runtime/pairing-broker.ts} +0 -0
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Moderation actions — the `moderate` tool's member/chat/topic operations,
|
|
3
|
-
* plus profile-photo lookup.
|
|
4
|
-
*
|
|
5
|
-
* Handlers call the Bot API directly and let Telegram's own errors surface
|
|
6
|
-
* (missing admin rights come back as descriptive 400s the model can read);
|
|
7
|
-
* pre-checking rights here would just race the real check.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import type { ChatPermissions } from "grammy/types";
|
|
11
|
-
import { toPositiveId } from "./shared.js";
|
|
12
|
-
import { resolveMediaInput } from "./media.js";
|
|
13
|
-
import { clearJoinRequest, listJoinRequests } from "../join-requests.js";
|
|
14
|
-
import type { TelegramActionHandlers } from "./types.js";
|
|
15
|
-
|
|
16
|
-
/** Seconds-from-now → Telegram until_date, honouring "omit = forever". */
|
|
17
|
-
function untilDate(minutes: unknown): number | undefined {
|
|
18
|
-
const n = Number(minutes);
|
|
19
|
-
if (!Number.isFinite(n) || n <= 0) return undefined;
|
|
20
|
-
return Math.floor(Date.now() / 1000) + Math.round(n * 60);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Friendly permission names → ChatPermissions. `send_media` fans out to all
|
|
25
|
-
* the per-kind media flags; raw `can_*` keys pass through untouched so the
|
|
26
|
-
* full API surface stays reachable.
|
|
27
|
-
*/
|
|
28
|
-
function toChatPermissions(raw: Record<string, boolean>): ChatPermissions {
|
|
29
|
-
const out: Record<string, boolean> = {};
|
|
30
|
-
const alias: Record<string, string[]> = {
|
|
31
|
-
send_messages: ["can_send_messages"],
|
|
32
|
-
send_media: [
|
|
33
|
-
"can_send_audios",
|
|
34
|
-
"can_send_documents",
|
|
35
|
-
"can_send_photos",
|
|
36
|
-
"can_send_videos",
|
|
37
|
-
"can_send_video_notes",
|
|
38
|
-
"can_send_voice_notes",
|
|
39
|
-
],
|
|
40
|
-
send_polls: ["can_send_polls"],
|
|
41
|
-
send_other: ["can_send_other_messages"],
|
|
42
|
-
web_previews: ["can_add_web_page_previews"],
|
|
43
|
-
change_info: ["can_change_info"],
|
|
44
|
-
invite_users: ["can_invite_users"],
|
|
45
|
-
pin_messages: ["can_pin_messages"],
|
|
46
|
-
manage_topics: ["can_manage_topics"],
|
|
47
|
-
};
|
|
48
|
-
for (const [key, value] of Object.entries(raw)) {
|
|
49
|
-
if (typeof value !== "boolean") continue;
|
|
50
|
-
for (const target of alias[key] ?? (key.startsWith("can_") ? [key] : [])) {
|
|
51
|
-
out[target] = value;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return out;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/** Everything a mute takes away; unmute grants it back. */
|
|
58
|
-
const FULL_MEMBER_PERMISSIONS: ChatPermissions = toChatPermissions({
|
|
59
|
-
send_messages: true,
|
|
60
|
-
send_media: true,
|
|
61
|
-
send_polls: true,
|
|
62
|
-
send_other: true,
|
|
63
|
-
web_previews: true,
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
/** The workaday admin kit `promote` grants; demote sets all of these false. */
|
|
67
|
-
const DEFAULT_ADMIN_RIGHTS = {
|
|
68
|
-
can_manage_chat: true,
|
|
69
|
-
can_delete_messages: true,
|
|
70
|
-
can_restrict_members: true,
|
|
71
|
-
can_pin_messages: true,
|
|
72
|
-
can_invite_users: true,
|
|
73
|
-
can_change_info: true,
|
|
74
|
-
can_manage_topics: true,
|
|
75
|
-
can_manage_video_chats: true,
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
export const moderationHandlers: TelegramActionHandlers = {
|
|
79
|
-
moderate: async (body, chatId, ctx) => {
|
|
80
|
-
const { bot, InputFileClass } = ctx;
|
|
81
|
-
const op = String(body.op ?? "");
|
|
82
|
-
const userId = toPositiveId(body.user_id);
|
|
83
|
-
const needsUser = [
|
|
84
|
-
"ban",
|
|
85
|
-
"unban",
|
|
86
|
-
"mute",
|
|
87
|
-
"unmute",
|
|
88
|
-
"promote",
|
|
89
|
-
"demote",
|
|
90
|
-
"set_admin_title",
|
|
91
|
-
"approve_join_request",
|
|
92
|
-
"decline_join_request",
|
|
93
|
-
];
|
|
94
|
-
if (needsUser.includes(op) && userId === undefined)
|
|
95
|
-
return { ok: false, error: `${op}: user_id is required` };
|
|
96
|
-
|
|
97
|
-
switch (op) {
|
|
98
|
-
case "ban":
|
|
99
|
-
await bot.api.banChatMember(chatId, userId!, {
|
|
100
|
-
until_date: untilDate(body.minutes),
|
|
101
|
-
revoke_messages: body.delete_messages === true || undefined,
|
|
102
|
-
});
|
|
103
|
-
return { ok: true };
|
|
104
|
-
case "unban":
|
|
105
|
-
// only_if_banned keeps this from kicking a current member.
|
|
106
|
-
await bot.api.unbanChatMember(chatId, userId!, {
|
|
107
|
-
only_if_banned: true,
|
|
108
|
-
});
|
|
109
|
-
return { ok: true };
|
|
110
|
-
case "mute":
|
|
111
|
-
await bot.api.restrictChatMember(
|
|
112
|
-
chatId,
|
|
113
|
-
userId!,
|
|
114
|
-
{ can_send_messages: false },
|
|
115
|
-
{ until_date: untilDate(body.minutes) },
|
|
116
|
-
);
|
|
117
|
-
return { ok: true };
|
|
118
|
-
case "unmute":
|
|
119
|
-
await bot.api.restrictChatMember(
|
|
120
|
-
chatId,
|
|
121
|
-
userId!,
|
|
122
|
-
FULL_MEMBER_PERMISSIONS,
|
|
123
|
-
);
|
|
124
|
-
return { ok: true };
|
|
125
|
-
case "promote":
|
|
126
|
-
await bot.api.promoteChatMember(chatId, userId!, DEFAULT_ADMIN_RIGHTS);
|
|
127
|
-
return { ok: true };
|
|
128
|
-
case "demote": {
|
|
129
|
-
const revoked = Object.fromEntries(
|
|
130
|
-
Object.keys(DEFAULT_ADMIN_RIGHTS).map((k) => [k, false]),
|
|
131
|
-
);
|
|
132
|
-
await bot.api.promoteChatMember(chatId, userId!, revoked);
|
|
133
|
-
return { ok: true };
|
|
134
|
-
}
|
|
135
|
-
case "set_admin_title":
|
|
136
|
-
await bot.api.setChatAdministratorCustomTitle(
|
|
137
|
-
chatId,
|
|
138
|
-
userId!,
|
|
139
|
-
String(body.title ?? ""),
|
|
140
|
-
);
|
|
141
|
-
return { ok: true };
|
|
142
|
-
case "set_permissions": {
|
|
143
|
-
const raw = body.permissions;
|
|
144
|
-
if (!raw || typeof raw !== "object")
|
|
145
|
-
return { ok: false, error: "set_permissions: permissions required" };
|
|
146
|
-
await bot.api.setChatPermissions(
|
|
147
|
-
chatId,
|
|
148
|
-
toChatPermissions(raw as Record<string, boolean>),
|
|
149
|
-
);
|
|
150
|
-
return { ok: true };
|
|
151
|
-
}
|
|
152
|
-
case "create_invite_link": {
|
|
153
|
-
const expireMin = Number(body.expire_minutes);
|
|
154
|
-
const link = await bot.api.createChatInviteLink(chatId, {
|
|
155
|
-
name: body.title ? String(body.title) : undefined,
|
|
156
|
-
expire_date:
|
|
157
|
-
Number.isFinite(expireMin) && expireMin > 0
|
|
158
|
-
? Math.floor(Date.now() / 1000) + Math.round(expireMin * 60)
|
|
159
|
-
: undefined,
|
|
160
|
-
member_limit: toPositiveId(body.member_limit),
|
|
161
|
-
});
|
|
162
|
-
return { ok: true, invite_link: link.invite_link };
|
|
163
|
-
}
|
|
164
|
-
case "revoke_invite_link": {
|
|
165
|
-
if (!body.link)
|
|
166
|
-
return { ok: false, error: "revoke_invite_link: link required" };
|
|
167
|
-
await bot.api.revokeChatInviteLink(chatId, String(body.link));
|
|
168
|
-
return { ok: true };
|
|
169
|
-
}
|
|
170
|
-
case "approve_join_request":
|
|
171
|
-
await bot.api.approveChatJoinRequest(chatId, userId!);
|
|
172
|
-
clearJoinRequest(chatId, userId!);
|
|
173
|
-
return { ok: true };
|
|
174
|
-
case "decline_join_request":
|
|
175
|
-
await bot.api.declineChatJoinRequest(chatId, userId!);
|
|
176
|
-
clearJoinRequest(chatId, userId!);
|
|
177
|
-
return { ok: true };
|
|
178
|
-
case "list_join_requests":
|
|
179
|
-
return { ok: true, requests: listJoinRequests(chatId) };
|
|
180
|
-
case "set_chat_photo": {
|
|
181
|
-
const resolved = resolveMediaInput(
|
|
182
|
-
body,
|
|
183
|
-
"set_chat_photo",
|
|
184
|
-
InputFileClass,
|
|
185
|
-
);
|
|
186
|
-
if ("error" in resolved) return { ok: false, error: resolved.error };
|
|
187
|
-
if (typeof resolved.file === "string")
|
|
188
|
-
return {
|
|
189
|
-
ok: false,
|
|
190
|
-
error: "set_chat_photo needs a local file_path (no url/file_id)",
|
|
191
|
-
};
|
|
192
|
-
await bot.api.setChatPhoto(chatId, resolved.file);
|
|
193
|
-
return { ok: true };
|
|
194
|
-
}
|
|
195
|
-
case "delete_chat_photo":
|
|
196
|
-
await bot.api.deleteChatPhoto(chatId);
|
|
197
|
-
return { ok: true };
|
|
198
|
-
case "unpin_all":
|
|
199
|
-
await bot.api.unpinAllChatMessages(chatId);
|
|
200
|
-
return { ok: true };
|
|
201
|
-
case "leave_chat":
|
|
202
|
-
await bot.api.leaveChat(chatId);
|
|
203
|
-
return { ok: true };
|
|
204
|
-
case "create_topic": {
|
|
205
|
-
if (!body.title)
|
|
206
|
-
return { ok: false, error: "create_topic: title required" };
|
|
207
|
-
const topic = await bot.api.createForumTopic(
|
|
208
|
-
chatId,
|
|
209
|
-
String(body.title),
|
|
210
|
-
);
|
|
211
|
-
return { ok: true, thread_id: topic.message_thread_id };
|
|
212
|
-
}
|
|
213
|
-
case "edit_topic": {
|
|
214
|
-
const threadId = toPositiveId(body.thread_id);
|
|
215
|
-
if (threadId === undefined)
|
|
216
|
-
return { ok: false, error: "edit_topic: thread_id required" };
|
|
217
|
-
await bot.api.editForumTopic(chatId, threadId, {
|
|
218
|
-
name: body.title ? String(body.title) : undefined,
|
|
219
|
-
});
|
|
220
|
-
return { ok: true };
|
|
221
|
-
}
|
|
222
|
-
case "close_topic":
|
|
223
|
-
case "reopen_topic":
|
|
224
|
-
case "delete_topic": {
|
|
225
|
-
const threadId = toPositiveId(body.thread_id);
|
|
226
|
-
if (threadId === undefined)
|
|
227
|
-
return { ok: false, error: `${op}: thread_id required` };
|
|
228
|
-
if (op === "close_topic")
|
|
229
|
-
await bot.api.closeForumTopic(chatId, threadId);
|
|
230
|
-
else if (op === "reopen_topic")
|
|
231
|
-
await bot.api.reopenForumTopic(chatId, threadId);
|
|
232
|
-
else await bot.api.deleteForumTopic(chatId, threadId);
|
|
233
|
-
return { ok: true };
|
|
234
|
-
}
|
|
235
|
-
default:
|
|
236
|
-
return { ok: false, error: `Unknown moderation op: ${op}` };
|
|
237
|
-
}
|
|
238
|
-
},
|
|
239
|
-
|
|
240
|
-
get_user_profile_photos: async (body, _chatId, { bot }) => {
|
|
241
|
-
const userId = toPositiveId(body.user_id);
|
|
242
|
-
if (userId === undefined)
|
|
243
|
-
return { ok: false, error: "user_id is required" };
|
|
244
|
-
const limit = toPositiveId(body.limit) ?? 5;
|
|
245
|
-
const photos = await bot.api.getUserProfilePhotos(userId, {
|
|
246
|
-
limit: Math.min(limit, 100),
|
|
247
|
-
});
|
|
248
|
-
return {
|
|
249
|
-
ok: true,
|
|
250
|
-
total: photos.total_count,
|
|
251
|
-
// Largest size of each photo; its file_id sends/downloads like media.
|
|
252
|
-
file_ids: photos.photos.map((sizes) => sizes[sizes.length - 1].file_id),
|
|
253
|
-
};
|
|
254
|
-
},
|
|
255
|
-
};
|
|
File without changes
|
|
File without changes
|