@zhin.js/adapter-telegram 1.1.0 → 1.1.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/README.md +5 -5
  3. package/adapters/{telegram.js → telegram/index.js} +6 -6
  4. package/adapters/{telegram.ts → telegram/index.ts} +9 -9
  5. package/agents/telegram/agent.json +20 -0
  6. package/agents/telegram/boundaries.md +3 -0
  7. package/agents/telegram/conventions.md +3 -0
  8. package/agents/telegram/skills/telegram-chat-admin/SKILL.md +24 -0
  9. package/agents/telegram/skills/telegram-chat-admin/tools/create_invite/index.js +18 -0
  10. package/{agent/tools/create_invite.ts → agents/telegram/skills/telegram-chat-admin/tools/create_invite/index.ts} +3 -3
  11. package/agents/telegram/skills/telegram-chat-admin/tools/list_admins/index.js +24 -0
  12. package/{agent/tools/list_admins.ts → agents/telegram/skills/telegram-chat-admin/tools/list_admins/index.ts} +1 -1
  13. package/agents/telegram/skills/telegram-chat-admin/tools/member_count/index.js +16 -0
  14. package/{agent/tools/member_count.ts → agents/telegram/skills/telegram-chat-admin/tools/member_count/index.ts} +1 -1
  15. package/agents/telegram/skills/telegram-chat-admin/tools/pin_message/index.js +19 -0
  16. package/{agent/tools/pin_message.ts → agents/telegram/skills/telegram-chat-admin/tools/pin_message/index.ts} +3 -3
  17. package/agents/telegram/skills/telegram-chat-admin/tools/set_description/index.js +17 -0
  18. package/{agent/tools/set_description.ts → agents/telegram/skills/telegram-chat-admin/tools/set_description/index.ts} +1 -1
  19. package/agents/telegram/skills/telegram-chat-admin/tools/set_permissions/index.js +32 -0
  20. package/{agent/tools/set_permissions.ts → agents/telegram/skills/telegram-chat-admin/tools/set_permissions/index.ts} +3 -3
  21. package/agents/telegram/skills/telegram-chat-admin/tools/unpin_message/index.js +19 -0
  22. package/{agent/tools/unpin_message.ts → agents/telegram/skills/telegram-chat-admin/tools/unpin_message/index.ts} +3 -3
  23. package/agents/telegram/skills/telegram-messages/SKILL.md +19 -0
  24. package/agents/telegram/skills/telegram-messages/tools/react/index.js +18 -0
  25. package/{agent/tools/react.ts → agents/telegram/skills/telegram-messages/tools/react/index.ts} +1 -1
  26. package/agents/telegram/skills/telegram-messages/tools/send_poll/index.js +30 -0
  27. package/{agent/tools/send_poll.ts → agents/telegram/skills/telegram-messages/tools/send_poll/index.ts} +1 -1
  28. package/agents/telegram/skills/telegram-messages/tools/send_sticker/index.js +17 -0
  29. package/{agent/tools/send_sticker.ts → agents/telegram/skills/telegram-messages/tools/send_sticker/index.ts} +1 -1
  30. package/agents/telegram/system.md +3 -0
  31. package/commands/{endpoint/add/[id].js → telegram/endpoint/add/[id]/index.js} +1 -1
  32. package/commands/telegram/endpoint/add/[id]/index.ts +3 -0
  33. package/{lib/telegram-endpoint-commands.js → commands/telegram/endpoint/definition.js} +4 -3
  34. package/{src/telegram-endpoint-commands.ts → commands/telegram/endpoint/definition.ts} +3 -3
  35. package/commands/{endpoint/list.js → telegram/endpoint/list/index.js} +1 -1
  36. package/commands/telegram/endpoint/list/index.ts +3 -0
  37. package/commands/{endpoint/remove/[id].js → telegram/endpoint/remove/[id]/index.js} +1 -1
  38. package/commands/telegram/endpoint/remove/[id]/index.ts +3 -0
  39. package/lib/index.d.ts +1 -1
  40. package/lib/protocol.d.ts +6 -14
  41. package/lib/protocol.js +15 -26
  42. package/lib/telegram-runtime-state.js +1 -1
  43. package/package.json +33 -21
  44. package/schema.json +32 -1
  45. package/src/index.ts +1 -1
  46. package/src/protocol.ts +20 -43
  47. package/src/telegram-runtime-state.ts +1 -1
  48. package/agent/skills/telegram.md +0 -103
  49. package/commands/endpoint/add/[id].ts +0 -3
  50. package/commands/endpoint/list.ts +0 -3
  51. package/commands/endpoint/remove/[id].ts +0 -3
  52. package/lib/telegram-endpoint-commands.d.ts +0 -1
  53. /package/{agent/PERMITS.md → PERMITS.md} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,98 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.2
4
+
5
+ ### Patch Changes
6
+
7
+ - a9e4a40: Derive Command user routes only from explicit `commands/**/*/index.ts(x)` entry paths instead of prepending the plugin owner. Child plugins can now publish top-level static or dynamic commands, while duplicate routes across owners fail during generation construction. Adapter endpoint commands move to explicit paths such as `commands/qq/endpoint/list/index.ts` and are invoked as `qq endpoint list`.
8
+ - 8740059: Standardize TypeScript capabilities on named module directories such as `commands/foo/index.ts`, `middlewares/audit/index.ts`, `handlers/message-receive/index.ts`, `pages/workroom/index.tsx`, and `mcps/filesystem/index.ts`. Only the fixed `index` entry is discovered; sibling files remain private helpers.
9
+
10
+ Command route segments come from directories, while `[name]`, `[[name]]`, `[...name]`, and `[[...name]]` directories declare dynamic parameters. Plugin owners do not enter the route unless their config explicitly sets `commandNamespace`; Endpoint `commandPrefix` remains platform-owned and defaults to an empty string.
11
+
12
+ Migrate the built-in adapters, plugins, examples, generators, migration tooling, hot reload classification, Agent authoring surfaces, documentation, and release artifacts to the explicit entry convention.
13
+
14
+ Make Tool ownership and progressive disclosure explicit across all four supported locations: plugin-public `tools/`, Agent-private `agents/<name>/tools/`, Skill-private `skills/<name>/tools/`, and Agent-Skill-private `agents/<name>/skills/<name>/tools/`. Move adapter and group-suite operations that require domain instructions into their owning Skills so `load_skill` is the only path that unlocks their schemas.
15
+
16
+ Remove the package-root `agent/` convention. Public capabilities now use named package-root directories, schedules use `schedules/<name>/index.ts` or `plugin.ts` injection, MCP connections use `mcps/<name>/index.ts`, Prompt Sections use `prompt-sections/<name>/index.ts`, Agent definitions use `agents/<name>/`, and permission vocabulary is published as `PERMITS.md`.
17
+
18
+ - 25a845a: Unify Skills on `skills/<name>/SKILL.md`, support Agent-private Skills and nested Skill-private Tools, publish and mount existing plugin Skills, add governed Skill metadata and Turn access filtering, unlock only already-admitted same-owner Tools, and make `on-risk` and `once` approval behavior precise.
19
+ - ddbb92e: Isolate adapter Skills under platform-specific Agents and automatically select the matching platform Agent for IM ingress, preventing unrelated adapter Skills from entering another platform's prompt surface.
20
+ - 40d2c8f: Reduce the default Agent Tool surface by moving process diagnostics into a Skill and splitting broad platform Skills into focused task domains. Restore ICQQ friend and group directory tools with `on-risk` approval and explicit owner, administrator, master, or trusted access.
21
+ - 4380cf9: Colocate adapter command definitions and Agent Skill handlers with their owning capabilities, and provide a shared validated platform permission constructor.
22
+ - 7b47680: Require the canonical expanded Telegram endpoint configuration. The protocol no longer reinterprets nested `endpoints` or reads endpoint identity, token, and webhook secret from `process.env`. The public config type is now `TelegramEndpointConfig`.
23
+ - 5c3858e: Make `@zhin.js/im-contract` the explicit zero-dependency owner of transport identities, canonical segments, media guards, conversation facts, stores, and delivery contracts. Platform adapters now read media contracts from that foundation instead of reaching through Core.
24
+ - 33ea736: Use `tools/<name>/index.ts` and `defineAgentTool` from `@zhin.js/tool` as the sole Agent Tool authoring model. Remove the duplicate `@zhin.js/tools` definition, context, bridge, export, and discovery path; migrate plugin manifests, examples, scaffolding, HMR, and prepack compilation to the generation-owned Tool Feature.
25
+ - Updated dependencies [c861789]
26
+ - Updated dependencies [1414ccb]
27
+ - Updated dependencies [743d470]
28
+ - Updated dependencies [62dee52]
29
+ - Updated dependencies [cd54131]
30
+ - Updated dependencies [244e475]
31
+ - Updated dependencies [a9e4a40]
32
+ - Updated dependencies [5855db7]
33
+ - Updated dependencies [ec921d2]
34
+ - Updated dependencies [8740059]
35
+ - Updated dependencies [63d1f7a]
36
+ - Updated dependencies [25a845a]
37
+ - Updated dependencies [103f2c3]
38
+ - Updated dependencies [9110ab8]
39
+ - Updated dependencies [cd2a888]
40
+ - Updated dependencies [eb3227a]
41
+ - Updated dependencies [b853dba]
42
+ - Updated dependencies [e561309]
43
+ - Updated dependencies [d4c6175]
44
+ - Updated dependencies [7a0e1ca]
45
+ - Updated dependencies [103b5d3]
46
+ - Updated dependencies [5a7a7f7]
47
+ - Updated dependencies [b076eae]
48
+ - Updated dependencies [535fed1]
49
+ - Updated dependencies [73a24b7]
50
+ - Updated dependencies [2dbbc15]
51
+ - Updated dependencies [1cb1163]
52
+ - Updated dependencies [be3061e]
53
+ - Updated dependencies [75f8332]
54
+ - Updated dependencies [81935e2]
55
+ - Updated dependencies [f9ed01b]
56
+ - Updated dependencies [ac0ab50]
57
+ - Updated dependencies [5140ce1]
58
+ - Updated dependencies [522d75f]
59
+ - Updated dependencies [a7611b3]
60
+ - Updated dependencies [8823044]
61
+ - Updated dependencies [379439b]
62
+ - Updated dependencies [11c9352]
63
+ - Updated dependencies [6b70e46]
64
+ - Updated dependencies [135ac91]
65
+ - Updated dependencies [140cf0f]
66
+ - Updated dependencies [251e4d2]
67
+ - Updated dependencies [203ad34]
68
+ - Updated dependencies [e6c5113]
69
+ - Updated dependencies [e0f6478]
70
+ - Updated dependencies [baef56b]
71
+ - Updated dependencies [698f16f]
72
+ - Updated dependencies [da0a8e3]
73
+ - Updated dependencies [2fd8017]
74
+ - Updated dependencies [5c3858e]
75
+ - Updated dependencies [33ea736]
76
+ - Updated dependencies [507d602]
77
+ - Updated dependencies [df9f76b]
78
+ - @zhin.js/core@1.1.37
79
+ - @zhin.js/tool@1.1.1
80
+ - @zhin.js/host-http@1.1.1
81
+ - @zhin.js/adapter@1.1.14
82
+ - @zhin.js/feature-kit@1.1.1
83
+ - @zhin.js/agent-feature@1.1.1
84
+ - @zhin.js/skill@1.1.1
85
+ - @zhin.js/logger@1.1.1
86
+ - @zhin.js/im-contract@1.1.1
87
+
88
+ ## 1.1.1
89
+
90
+ ### Patch Changes
91
+
92
+ - Updated dependencies [769e67f]
93
+ - @zhin.js/adapter@1.1.13
94
+ - @zhin.js/core@1.1.36
95
+
3
96
  ## 1.1.0
4
97
 
5
98
  ### Minor Changes
package/README.md CHANGED
@@ -19,7 +19,7 @@ pnpm add @zhin.js/adapter-telegram
19
19
 
20
20
  ## Plugin Runtime
21
21
 
22
- - `@zhin.js/adapter` — 约定式 `adapters/telegram.ts`(`defineAdapter`)
22
+ - `@zhin.js/adapter` — 约定式 `adapters/telegram/index.ts`(`defineAdapter`)
23
23
  - `@zhin.js/core` — `Endpoint.emit(...)` 入站、`outboundMessageToken` 出站
24
24
  - `zhin.js` — `plugin.ts`(`definePlugin`)
25
25
  - 配置经插件 `schema.json` 落到 `plugins.<instanceKey>`
@@ -62,8 +62,8 @@ plugins:
62
62
 
63
63
  | 变量 | 说明 |
64
64
  |------|------|
65
- | `TELEGRAM_TOKEN` / `TELEGRAM_BOT_TOKEN` | Bot Token |
66
- | `TELEGRAM_BOT_NAME` | 可选,默认 endpoint 名 |
65
+ | `TELEGRAM_TOKEN` | 示例中由 YAML `${TELEGRAM_TOKEN}` 引用的 Bot Token;变量名可自行定义 |
66
+ | `TELEGRAM_WEBHOOK_SECRET` | 示例中由 YAML `${TELEGRAM_WEBHOOK_SECRET}` 引用的 webhook secret;变量名可自行定义 |
67
67
 
68
68
  ## Webhook
69
69
 
@@ -115,8 +115,8 @@ Webhook 接收确认不等于业务处理完成;需要幂等性的业务应自
115
115
 
116
116
  | Kind | Path |
117
117
  |------|------|
118
- | Platform tools (10) | `agent/tools/`(invite / pin / admins / sticker / poll 等) |
119
- | Skill doc | `agent/skills/telegram.md` |
118
+ | Platform tools (10) | `tools/`(invite / pin / admins / sticker / poll 等) |
119
+ | Skill doc | `agents/telegram/skills/telegram-chat-admin/SKILL.md`, `agents/telegram/skills/telegram-messages/SKILL.md` |
120
120
 
121
121
  ## 故障排查
122
122
 
@@ -1,13 +1,13 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  /**
3
- * Convention entry: discover `adapters/telegram.ts` → defineAdapter.
3
+ * Convention entry: discover `adapters/telegram/index.ts` → defineAdapter.
4
4
  */
5
5
  import { defineAdapter } from 'zhin.js/adapter';
6
6
  import { httpHostToken } from '@zhin.js/host-http';
7
- import { TelegramEndpoint } from "../lib/endpoint.js";
8
- import { resolveTelegramConfig, } from "../lib/protocol.js";
9
- import { telegramRuntimeStateToken } from "../lib/telegram-runtime-state.js";
10
- export { TelegramEndpoint } from "../lib/endpoint.js";
7
+ import { TelegramEndpoint } from "../../lib/endpoint.js";
8
+ import { resolveTelegramConfig, } from "../../lib/protocol.js";
9
+ import { telegramRuntimeStateToken } from "../../lib/telegram-runtime-state.js";
10
+ export { TelegramEndpoint } from "../../lib/endpoint.js";
11
11
  export default defineAdapter({
12
12
  capabilities: ['inbound', 'outbound'],
13
13
  operations: ['recall'],
@@ -20,7 +20,7 @@ export default defineAdapter({
20
20
  },
21
21
  create(context) {
22
22
  const config = resolveTelegramConfig(context.config);
23
- // 注册到插件运行时状态(telegram.endpoint list 的"运行中"数据源)
23
+ // 注册到插件运行时状态(telegram endpoint list 的"运行中"数据源)
24
24
  context.use(telegramRuntimeStateToken).endpoints.set(config.id, {
25
25
  id: config.id,
26
26
  mode: config.mode,
@@ -1,19 +1,19 @@
1
1
  /**
2
- * Convention entry: discover `adapters/telegram.ts` → defineAdapter.
2
+ * Convention entry: discover `adapters/telegram/index.ts` → defineAdapter.
3
3
  */
4
4
  import { defineAdapter } from 'zhin.js/adapter';
5
5
  import { httpHostToken } from '@zhin.js/host-http';
6
- import { TelegramEndpoint } from '../src/endpoint.js';
6
+ import { TelegramEndpoint } from '../../src/endpoint.js';
7
7
  import {
8
8
  resolveTelegramConfig,
9
- type TelegramAdapterConfig,
10
- } from '../src/protocol.js';
11
- import { telegramRuntimeStateToken } from '../src/telegram-runtime-state.js';
9
+ type TelegramEndpointConfig,
10
+ } from '../../src/protocol.js';
11
+ import { telegramRuntimeStateToken } from '../../src/telegram-runtime-state.js';
12
12
 
13
- export { TelegramEndpoint } from '../src/endpoint.js';
14
- export type { TelegramEndpointOptions, TelegramFetch } from '../src/endpoint.js';
13
+ export { TelegramEndpoint } from '../../src/endpoint.js';
14
+ export type { TelegramEndpointOptions, TelegramFetch } from '../../src/endpoint.js';
15
15
 
16
- export default defineAdapter<TelegramAdapterConfig>({
16
+ export default defineAdapter<TelegramEndpointConfig>({
17
17
  capabilities: ['inbound', 'outbound'],
18
18
  operations: ['recall'],
19
19
  // 媒体 url / file_id 直发,base64 / 本地路径经 multipart attach:// 上传物化;
@@ -25,7 +25,7 @@ export default defineAdapter<TelegramAdapterConfig>({
25
25
  },
26
26
  create(context) {
27
27
  const config = resolveTelegramConfig(context.config);
28
- // 注册到插件运行时状态(telegram.endpoint list 的"运行中"数据源)
28
+ // 注册到插件运行时状态(telegram endpoint list 的"运行中"数据源)
29
29
  context.use(telegramRuntimeStateToken).endpoints.set(config.id, {
30
30
  id: config.id,
31
31
  mode: config.mode,
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "TELEGRAM Platform Agent",
3
+ "version": "1.0.0",
4
+ "description": "Handles telegram platform-specific operations and progressively loads only the required platform Skill.",
5
+ "trigger_rules": {
6
+ "file_patterns": [],
7
+ "keywords": [
8
+ "telegram",
9
+ "adapter:telegram"
10
+ ]
11
+ },
12
+ "entry_points": [
13
+ "system.md",
14
+ "boundaries.md",
15
+ "conventions.md"
16
+ ],
17
+ "platforms": [
18
+ "telegram"
19
+ ]
20
+ }
@@ -0,0 +1,3 @@
1
+ # Boundaries
2
+
3
+ Operate only on the active telegram endpoint and authenticated conversation context. Respect every Tool permission and approval policy. Do not infer identifiers, roles, or authorization from display names.
@@ -0,0 +1,3 @@
1
+ # Conventions
2
+
3
+ Use stable platform identifiers from the current turn or directory queries. Load one task-specific Skill at a time, and use the unified reply and outbound message path.
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: telegram-chat-admin
3
+ platforms:
4
+ - telegram
5
+ description: Telegram 管理员查询、成员数、邀请、置顶和群权限设置能力。
6
+ keywords:
7
+ - "telegram"
8
+ - "admin"
9
+ - "invite"
10
+ - "pin"
11
+ - "permissions"
12
+ tools:
13
+ - "pin_message"
14
+ - "unpin_message"
15
+ - "list_admins"
16
+ - "member_count"
17
+ - "create_invite"
18
+ - "set_permissions"
19
+ - "set_description"
20
+ ---
21
+
22
+ # telegram-chat-admin
23
+
24
+ 先读取管理员与成员状态,再执行邀请、置顶或权限变更。群设置写操作遵守审批策略。
@@ -0,0 +1,18 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ import { platformPermission } from '@zhin.js/permission';
5
+ export default defineAgentTool({
6
+ description: '创建 Telegram 群组邀请链接',
7
+ inputSchema: z.object({
8
+ chat_id: z.string().describe('聊天 ID'),
9
+ }),
10
+ adapter: 'telegram',
11
+ tags: ['telegram'],
12
+ permissions: [platformPermission('telegram', 'chat_administrator')],
13
+ async execute({ chat_id }, context) {
14
+ const endpoint = context.$client;
15
+ const link = await endpoint.createInviteLink(Number(chat_id));
16
+ return { invite_link: link, message: `邀请链接: ${link}` };
17
+ },
18
+ });
@@ -1,6 +1,6 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
- import { platformPermit } from '../../src/platform-permit.js';
3
+ import { platformPermission } from '@zhin.js/permission';
4
4
 
5
5
  export default defineAgentTool<{ chat_id: string }>({
6
6
  description: '创建 Telegram 群组邀请链接',
@@ -9,7 +9,7 @@ export default defineAgentTool<{ chat_id: string }>({
9
9
  }),
10
10
  adapter: 'telegram',
11
11
  tags: ['telegram'],
12
- permissions: [platformPermit('chat_administrator')],
12
+ permissions: [platformPermission('telegram', 'chat_administrator')],
13
13
  async execute({ chat_id }: { chat_id: string }, context) {
14
14
  const endpoint = context.$client;
15
15
  const link = await endpoint.createInviteLink(Number(chat_id));
@@ -0,0 +1,24 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ export default defineAgentTool({
5
+ description: '获取 Telegram 群组管理员列表',
6
+ inputSchema: z.object({
7
+ chat_id: z.string().describe('聊天 ID'),
8
+ }),
9
+ adapter: 'telegram',
10
+ tags: ['telegram'],
11
+ async execute({ chat_id }, context) {
12
+ const endpoint = context.$client;
13
+ const admins = await endpoint.getChatAdmins(Number(chat_id));
14
+ return {
15
+ admins: admins.map((a) => ({
16
+ user_id: a.user.id,
17
+ username: a.user.username,
18
+ first_name: a.user.first_name,
19
+ status: a.status,
20
+ })),
21
+ count: admins.length,
22
+ };
23
+ },
24
+ });
@@ -1,4 +1,4 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
3
 
4
4
  export default defineAgentTool<{ chat_id: string }>({
@@ -0,0 +1,16 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ export default defineAgentTool({
5
+ description: '获取 Telegram 群组成员数量',
6
+ inputSchema: z.object({
7
+ chat_id: z.string().describe('聊天 ID'),
8
+ }),
9
+ adapter: 'telegram',
10
+ tags: ['telegram'],
11
+ async execute({ chat_id }, context) {
12
+ const endpoint = context.$client;
13
+ const count = await endpoint.getChatMemberCount(Number(chat_id));
14
+ return { count, message: `群组共有 ${count} 名成员` };
15
+ },
16
+ });
@@ -1,4 +1,4 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
3
 
4
4
  export default defineAgentTool<{ chat_id: string }>({
@@ -0,0 +1,19 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ import { platformPermission } from '@zhin.js/permission';
5
+ export default defineAgentTool({
6
+ description: '置顶 Telegram 群组消息',
7
+ inputSchema: z.object({
8
+ chat_id: z.string().describe('聊天 ID'),
9
+ message_id: z.string().describe('消息 ID'),
10
+ }),
11
+ adapter: 'telegram',
12
+ tags: ['telegram'],
13
+ permissions: [platformPermission('telegram', 'pin_messages')],
14
+ async execute({ chat_id, message_id }, context) {
15
+ const endpoint = context.$client;
16
+ const success = await endpoint.pinMessage(Number(chat_id), Number(message_id));
17
+ return { success, message: success ? '消息已置顶' : '操作失败' };
18
+ },
19
+ });
@@ -1,6 +1,6 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
- import { platformPermit } from '../../src/platform-permit.js';
3
+ import { platformPermission } from '@zhin.js/permission';
4
4
 
5
5
  export default defineAgentTool<{ chat_id: string; message_id: string }>({
6
6
  description: '置顶 Telegram 群组消息',
@@ -10,7 +10,7 @@ export default defineAgentTool<{ chat_id: string; message_id: string }>({
10
10
  }),
11
11
  adapter: 'telegram',
12
12
  tags: ['telegram'],
13
- permissions: [platformPermit('pin_messages')],
13
+ permissions: [platformPermission('telegram', 'pin_messages')],
14
14
  async execute({ chat_id, message_id }: { chat_id: string; message_id: string }, context) {
15
15
  const endpoint = context.$client;
16
16
  const success = await endpoint.pinMessage(Number(chat_id), Number(message_id));
@@ -0,0 +1,17 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ export default defineAgentTool({
5
+ description: '设置 Telegram 群组描述',
6
+ inputSchema: z.object({
7
+ chat_id: z.string().describe('聊天 ID'),
8
+ description: z.string().describe('群描述文字'),
9
+ }),
10
+ adapter: 'telegram',
11
+ tags: ['telegram'],
12
+ async execute({ chat_id, description }, context) {
13
+ const endpoint = context.$client;
14
+ const success = await endpoint.setChatDescription(Number(chat_id), description);
15
+ return { success, message: success ? '群描述已更新' : '操作失败' };
16
+ },
17
+ });
@@ -1,4 +1,4 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
3
 
4
4
  export default defineAgentTool<{ chat_id: string; description: string }>({
@@ -0,0 +1,32 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ import { platformPermission } from '@zhin.js/permission';
5
+ export default defineAgentTool({
6
+ description: '设置 Telegram 群组的默认成员权限',
7
+ inputSchema: z.object({
8
+ chat_id: z.string().describe('聊天 ID'),
9
+ can_send_messages: z.boolean().optional().describe('是否可以发消息'),
10
+ can_send_photos: z.boolean().optional().describe('是否可以发图片'),
11
+ can_send_videos: z.boolean().optional().describe('是否可以发视频'),
12
+ can_send_polls: z.boolean().optional().describe('是否可以发投票'),
13
+ can_send_other_messages: z.boolean().optional().describe('是否可以发贴纸/GIF等'),
14
+ can_add_web_page_previews: z.boolean().optional().describe('是否可以添加网页预览'),
15
+ can_change_info: z.boolean().optional().describe('是否可以改群信息'),
16
+ can_invite_users: z.boolean().optional().describe('是否可以邀请用户'),
17
+ can_pin_messages: z.boolean().optional().describe('是否可以置顶消息'),
18
+ }),
19
+ adapter: 'telegram',
20
+ tags: ['telegram'],
21
+ permissions: [platformPermission('telegram', 'manage_chat')],
22
+ async execute({ chat_id, ...perms }, context) {
23
+ const endpoint = context.$client;
24
+ const permissions = {};
25
+ for (const [k, v] of Object.entries(perms)) {
26
+ if (typeof v === 'boolean')
27
+ permissions[k] = v;
28
+ }
29
+ const success = await endpoint.setChatPermissionsAll(Number(chat_id), permissions);
30
+ return { success, message: success ? '群权限已更新' : '操作失败' };
31
+ },
32
+ });
@@ -1,6 +1,6 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
- import { platformPermit } from '../../src/platform-permit.js';
3
+ import { platformPermission } from '@zhin.js/permission';
4
4
 
5
5
  export default defineAgentTool<{ chat_id: string; can_send_messages?: boolean; can_send_photos?: boolean; can_send_videos?: boolean; can_send_polls?: boolean; can_send_other_messages?: boolean; can_add_web_page_previews?: boolean; can_change_info?: boolean; can_invite_users?: boolean; can_pin_messages?: boolean }>({
6
6
  description: '设置 Telegram 群组的默认成员权限',
@@ -18,7 +18,7 @@ export default defineAgentTool<{ chat_id: string; can_send_messages?: boolean; c
18
18
  }),
19
19
  adapter: 'telegram',
20
20
  tags: ['telegram'],
21
- permissions: [platformPermit('manage_chat')],
21
+ permissions: [platformPermission('telegram', 'manage_chat')],
22
22
  async execute({ chat_id, ...perms }: { chat_id: string; can_send_messages?: boolean; can_send_photos?: boolean; can_send_videos?: boolean; can_send_polls?: boolean; can_send_other_messages?: boolean; can_add_web_page_previews?: boolean; can_change_info?: boolean; can_invite_users?: boolean; can_pin_messages?: boolean }, context) {
23
23
  const endpoint = context.$client;
24
24
  const permissions: Record<string, boolean> = {};
@@ -0,0 +1,19 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ import { platformPermission } from '@zhin.js/permission';
5
+ export default defineAgentTool({
6
+ description: '取消置顶 Telegram 群组消息',
7
+ inputSchema: z.object({
8
+ chat_id: z.string().describe('聊天 ID'),
9
+ message_id: z.string().optional().describe('消息 ID(可选,不提供则取消所有置顶)'),
10
+ }),
11
+ adapter: 'telegram',
12
+ tags: ['telegram'],
13
+ permissions: [platformPermission('telegram', 'pin_messages')],
14
+ async execute({ chat_id, message_id }, context) {
15
+ const endpoint = context.$client;
16
+ const success = await endpoint.unpinMessage(Number(chat_id), message_id ? Number(message_id) : undefined);
17
+ return { success, message: success ? '已取消置顶' : '操作失败' };
18
+ },
19
+ });
@@ -1,6 +1,6 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
- import { platformPermit } from '../../src/platform-permit.js';
3
+ import { platformPermission } from '@zhin.js/permission';
4
4
 
5
5
  export default defineAgentTool<{ chat_id: string; message_id?: string }>({
6
6
  description: '取消置顶 Telegram 群组消息',
@@ -10,7 +10,7 @@ export default defineAgentTool<{ chat_id: string; message_id?: string }>({
10
10
  }),
11
11
  adapter: 'telegram',
12
12
  tags: ['telegram'],
13
- permissions: [platformPermit('pin_messages')],
13
+ permissions: [platformPermission('telegram', 'pin_messages')],
14
14
  async execute({ chat_id, message_id }: { chat_id: string; message_id?: string }, context) {
15
15
  const endpoint = context.$client;
16
16
  const success = await endpoint.unpinMessage(Number(chat_id), message_id ? Number(message_id) : undefined);
@@ -0,0 +1,19 @@
1
+ ---
2
+ name: telegram-messages
3
+ platforms:
4
+ - telegram
5
+ description: Telegram 投票、reaction 和贴纸消息能力。
6
+ keywords:
7
+ - "telegram"
8
+ - "poll"
9
+ - "reaction"
10
+ - "sticker"
11
+ tools:
12
+ - "send_poll"
13
+ - "react"
14
+ - "send_sticker"
15
+ ---
16
+
17
+ # telegram-messages
18
+
19
+ 用于消息互动。确认聊天和目标消息后调用,避免重复发送。
@@ -0,0 +1,18 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ export default defineAgentTool({
5
+ description: '对 Telegram 消息添加表情反应',
6
+ inputSchema: z.object({
7
+ chat_id: z.string().describe('聊天 ID'),
8
+ message_id: z.string().describe('消息 ID'),
9
+ reaction: z.string().describe('反应表情(如 👍、❤️、🔥)'),
10
+ }),
11
+ adapter: 'telegram',
12
+ tags: ['telegram'],
13
+ async execute({ chat_id, message_id, reaction }, context) {
14
+ const endpoint = context.$client;
15
+ const success = await endpoint.setMessageReaction(Number(chat_id), Number(message_id), reaction);
16
+ return { success, message: success ? `已添加反应 ${reaction}` : '操作失败' };
17
+ },
18
+ });
@@ -1,4 +1,4 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
3
 
4
4
  export default defineAgentTool<{ chat_id: string; message_id: string; reaction: string }>({
@@ -0,0 +1,30 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ export default defineAgentTool({
5
+ description: '在 Telegram 群组中发起投票',
6
+ inputSchema: z.object({
7
+ chat_id: z.string().describe('聊天 ID'),
8
+ question: z.string().describe('投票问题'),
9
+ options: z.string().describe('选项 JSON 数组,如 ["A","B","C"]'),
10
+ is_anonymous: z.boolean().optional().describe('是否匿名投票,默认 true'),
11
+ allows_multiple: z.boolean().optional().describe('是否允许多选,默认 false'),
12
+ }),
13
+ adapter: 'telegram',
14
+ tags: ['telegram'],
15
+ async execute({ chat_id, question, options, is_anonymous, allows_multiple }, context) {
16
+ const endpoint = context.$client;
17
+ let optList;
18
+ try {
19
+ optList = JSON.parse(options);
20
+ }
21
+ catch {
22
+ return { success: false, message: 'options 格式错误,应为 JSON 数组' };
23
+ }
24
+ if (!Array.isArray(optList) || optList.length < 2) {
25
+ return { success: false, message: '至少需要 2 个选项' };
26
+ }
27
+ const result = await endpoint.sendPoll(Number(chat_id), question, optList, is_anonymous ?? true, allows_multiple ?? false);
28
+ return { success: true, message_id: result.message_id, message: '投票已发送' };
29
+ },
30
+ });
@@ -1,4 +1,4 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
3
 
4
4
  export default defineAgentTool<{ chat_id: string; question: string; options: string; is_anonymous?: boolean; allows_multiple?: boolean }>({
@@ -0,0 +1,17 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ export default defineAgentTool({
5
+ description: '发送 Telegram 贴纸',
6
+ inputSchema: z.object({
7
+ chat_id: z.string().describe('聊天 ID'),
8
+ sticker: z.string().describe('贴纸 file_id 或 URL'),
9
+ }),
10
+ adapter: 'telegram',
11
+ tags: ['telegram'],
12
+ async execute({ chat_id, sticker }, context) {
13
+ const endpoint = context.$client;
14
+ const result = await endpoint.sendStickerMessage(Number(chat_id), sticker);
15
+ return { success: true, message_id: result.message_id, message: '贴纸已发送' };
16
+ },
17
+ });
@@ -1,4 +1,4 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
3
 
4
4
  export default defineAgentTool<{ chat_id: string; sticker: string }>({
@@ -0,0 +1,3 @@
1
+ # TELEGRAM Platform Agent
2
+
3
+ You are the telegram platform specialist. Interpret requests in the current telegram conversation and load only the narrowest private Skill needed for the task.
@@ -1,3 +1,3 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { telegramEndpointCommands } from "../../../lib/telegram-endpoint-commands.js";
2
+ import { telegramEndpointCommands } from '../../definition.js';
3
3
  export default telegramEndpointCommands.add;
@@ -0,0 +1,3 @@
1
+ import { telegramEndpointCommands } from '../../definition.js';
2
+
3
+ export default telegramEndpointCommands.add;
@@ -1,10 +1,11 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
1
2
  /**
2
- * `telegram.endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
- * commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
3
+ * `telegram endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
4
+ * commands/telegram/endpoint/ 下的 list / add / remove 直接默认导出这三项。
4
5
  */
5
6
  import { createEndpointCommands } from 'zhin.js/adapter';
6
7
  import { defineCommand } from 'zhin.js/command';
7
- import { telegramRuntimeStateToken } from './telegram-runtime-state.js';
8
+ import { telegramRuntimeStateToken } from "../../../lib/telegram-runtime-state.js";
8
9
  export const telegramEndpointCommands = createEndpointCommands({
9
10
  adapterKey: 'telegram',
10
11
  adapterDisplayName: 'Telegram',
@@ -1,10 +1,10 @@
1
1
  /**
2
- * `telegram.endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
- * commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
2
+ * `telegram endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
+ * commands/telegram/endpoint/ 下的 list / add / remove 直接默认导出这三项。
4
4
  */
5
5
  import { createEndpointCommands } from 'zhin.js/adapter';
6
6
  import { defineCommand } from 'zhin.js/command';
7
- import { telegramRuntimeStateToken } from './telegram-runtime-state.js';
7
+ import { telegramRuntimeStateToken } from '../../../src/telegram-runtime-state.js';
8
8
 
9
9
  export const telegramEndpointCommands = createEndpointCommands({
10
10
  adapterKey: 'telegram',
@@ -1,3 +1,3 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { telegramEndpointCommands } from "../../lib/telegram-endpoint-commands.js";
2
+ import { telegramEndpointCommands } from '../definition.js';
3
3
  export default telegramEndpointCommands.list;
@@ -0,0 +1,3 @@
1
+ import { telegramEndpointCommands } from '../definition.js';
2
+
3
+ export default telegramEndpointCommands.list;
@@ -1,3 +1,3 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { telegramEndpointCommands } from "../../../lib/telegram-endpoint-commands.js";
2
+ import { telegramEndpointCommands } from '../../definition.js';
3
3
  export default telegramEndpointCommands.remove;
@@ -0,0 +1,3 @@
1
+ import { telegramEndpointCommands } from '../../definition.js';
2
+
3
+ export default telegramEndpointCommands.remove;
package/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { TelegramClient, TelegramEndpoint, type TelegramClientApi, type TelegramEndpointOptions, type TelegramFetch, } from './endpoint.js';
2
- export { botApiUrl, formatCallbackContent, formatInboundContent, formatOutboundActions, formatOutboundPlan, normalizeWebhookPath, resolveTelegramConfig, senderDisplayName, type ResolvedTelegramConfig, type TelegramAdapterConfig, type TelegramCallbackQuery, type TelegramChat, type TelegramChatMember, type TelegramMessage, type TelegramOutboundAction, type TelegramOutboundPlan, type TelegramOutboundUpload, type TelegramUpdate, type TelegramUser, type TelegramWireSegment, } from './protocol.js';
2
+ export { botApiUrl, formatCallbackContent, formatInboundContent, formatOutboundActions, formatOutboundPlan, normalizeWebhookPath, resolveTelegramConfig, senderDisplayName, type ResolvedTelegramConfig, type TelegramEndpointConfig, type TelegramCallbackQuery, type TelegramChat, type TelegramChatMember, type TelegramMessage, type TelegramOutboundAction, type TelegramOutboundPlan, type TelegramOutboundUpload, type TelegramUpdate, type TelegramUser, type TelegramWireSegment, } from './protocol.js';
3
3
  export { telegramClient, type TelegramClientEventMap } from './client.js';
4
4
  export { checkTelegramPlatformPermit, normalizeTelegramChatMember, platformPermit, telegramGroupPermitResolver, } from './platform-permit.js';
package/lib/protocol.d.ts CHANGED
@@ -3,12 +3,12 @@
3
3
  * Canonicalization is owned by gateway/core before endpoint.send.
4
4
  */
5
5
  import type { IncomingMessage } from 'node:http';
6
+ import { type ConversationKind, type ConversationRef } from '@zhin.js/im-contract';
6
7
  import type { Segment } from '@zhin.js/core/runtime';
7
- import type { ConversationKind, ConversationRef } from '@zhin.js/im-contract';
8
- /** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
9
- export interface TelegramAdapterConfig {
10
- readonly id?: string;
11
- readonly token?: string;
8
+ /** One endpoint config after AdapterIndex expands `plugins.<instanceKey>.endpoints`. */
9
+ export interface TelegramEndpointConfig {
10
+ readonly id: string;
11
+ readonly token: string;
12
12
  /** Default true. `false` selects webhook mode (requires httpHostToken). */
13
13
  readonly polling?: boolean;
14
14
  readonly webhook?: {
@@ -18,14 +18,6 @@ export interface TelegramAdapterConfig {
18
18
  };
19
19
  readonly allowedUpdates?: readonly string[];
20
20
  readonly apiBaseUrl?: string;
21
- /** Transitional: legacy root `endpoints[]` with `context: telegram`. */
22
- readonly endpoints?: ReadonlyArray<Partial<ResolvedTelegramConfig> & {
23
- readonly context?: string;
24
- readonly polling?: boolean;
25
- readonly webhook?: TelegramAdapterConfig['webhook'];
26
- readonly allowedUpdates?: readonly string[];
27
- readonly apiBaseUrl?: string;
28
- }>;
29
21
  }
30
22
  export interface ResolvedTelegramConfig {
31
23
  readonly context: 'telegram';
@@ -236,7 +228,7 @@ export type TelegramOutboundAction = {
236
228
  };
237
229
  };
238
230
  };
239
- export declare function resolveTelegramConfig(config?: TelegramAdapterConfig): ResolvedTelegramConfig;
231
+ export declare function resolveTelegramConfig(config: TelegramEndpointConfig): ResolvedTelegramConfig;
240
232
  export declare function normalizeWebhookPath(path: string): string;
241
233
  export declare function buildWebhookUrl(webhook: NonNullable<ResolvedTelegramConfig['webhook']>): string;
242
234
  export declare function readTextBody(request: IncomingMessage, options?: {
package/lib/protocol.js CHANGED
@@ -2,40 +2,23 @@
2
2
  * Telegram Bot API protocol helpers — no legacy Adapter/Endpoint / segment-mapper.
3
3
  * Canonicalization is owned by gateway/core before endpoint.send.
4
4
  */
5
- import { isMediaRef } from '@zhin.js/core';
5
+ import { isMediaRef } from '@zhin.js/im-contract';
6
6
  import { formatCompact, getLogger } from '@zhin.js/logger';
7
7
  import { escapeTelegramHtml, markdownToTelegramHtml } from './markdown-to-html.js';
8
8
  const logger = getLogger('telegram');
9
- export function resolveTelegramConfig(config = {}) {
10
- const entry = config.endpoints?.find((item) => item.context === 'telegram');
11
- const token = config.token
12
- ?? entry?.token
13
- ?? process.env.TELEGRAM_TOKEN
14
- ?? process.env.TELEGRAM_BOT_TOKEN;
15
- if (!token) {
16
- throw new TypeError('Telegram adapter requires token (plugins.<key>.token or endpoints with context: telegram)');
17
- }
18
- const id = (typeof config.id === 'string' && config.id)
19
- || (typeof entry?.id === 'string' && entry.id)
20
- || process.env.TELEGRAM_BOT_NAME
21
- || 'telegram-bot';
22
- const polling = config.polling ?? entry?.polling;
23
- const webhookSource = config.webhook ?? entry?.webhook;
24
- // Match legacy: polling defaults true; webhook only when polling === false.
9
+ export function resolveTelegramConfig(config) {
10
+ const id = requiredEndpointField(config.id, 'id');
11
+ const token = requiredEndpointField(config.token, 'token');
12
+ const polling = config.polling;
13
+ const webhookSource = config.webhook;
25
14
  const mode = polling === false ? 'webhook' : 'polling';
26
- const apiBaseUrl = (config.apiBaseUrl
27
- ?? entry?.apiBaseUrl
28
- ?? 'https://api.telegram.org').replace(/\/$/, '');
29
- const allowedUpdates = config.allowedUpdates
30
- ?? entry?.allowedUpdates
31
- ?? ['message', 'callback_query'];
15
+ const apiBaseUrl = (config.apiBaseUrl ?? 'https://api.telegram.org').replace(/\/$/, '');
16
+ const allowedUpdates = config.allowedUpdates ?? ['message', 'callback_query'];
32
17
  const webhook = mode === 'webhook'
33
18
  ? {
34
19
  domain: webhookSource?.domain ?? '',
35
20
  path: normalizeWebhookPath(webhookSource?.path ?? '/telegram/webhook'),
36
- secretToken: webhookSource?.secretToken
37
- ?? process.env.TELEGRAM_WEBHOOK_SECRET
38
- ?? undefined,
21
+ secretToken: webhookSource?.secretToken,
39
22
  }
40
23
  : undefined;
41
24
  return {
@@ -48,6 +31,12 @@ export function resolveTelegramConfig(config = {}) {
48
31
  webhook,
49
32
  };
50
33
  }
34
+ function requiredEndpointField(value, field) {
35
+ if (typeof value !== 'string' || !value.trim()) {
36
+ throw new TypeError(`Telegram endpoint requires a non-empty ${field}`);
37
+ }
38
+ return value.trim();
39
+ }
51
40
  export function normalizeWebhookPath(path) {
52
41
  const trimmed = path.trim() || '/telegram/webhook';
53
42
  return trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Telegram 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
3
- * 由 plugin.ts setup() provide,adapter create 与 `telegram.endpoint` 命令共享(同一 owner generation)。
3
+ * 由 plugin.ts setup() provide,adapter create 与 `telegram endpoint` 命令共享(同一 owner generation)。
4
4
  */
5
5
  import { defineEndpointRuntimeStateToken } from 'zhin.js/adapter';
6
6
  export const telegramRuntimeStateToken = defineEndpointRuntimeStateToken('telegram');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-telegram",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Zhin.js Telegram Bot API adapter for Plugin Runtime (long-poll getUpdates)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -32,26 +32,25 @@
32
32
  "directory": "plugins/adapters/telegram"
33
33
  },
34
34
  "dependencies": {
35
- "@zhin.js/adapter": "1.1.12",
36
- "@zhin.js/core": "1.1.35",
37
- "@zhin.js/feature-kit": "1.1.0",
38
- "@zhin.js/host-http": "1.1.0",
39
- "@zhin.js/im-contract": "1.1.0",
40
- "@zhin.js/logger": "1.1.0"
35
+ "@zhin.js/adapter": "1.1.14",
36
+ "@zhin.js/agent-feature": "1.1.1",
37
+ "@zhin.js/core": "1.1.37",
38
+ "@zhin.js/feature-kit": "1.1.1",
39
+ "@zhin.js/host-http": "1.1.1",
40
+ "@zhin.js/im-contract": "1.1.1",
41
+ "@zhin.js/logger": "1.1.1",
42
+ "@zhin.js/skill": "1.1.1",
43
+ "@zhin.js/tool": "1.1.1"
41
44
  },
42
45
  "peerDependencies": {
43
46
  "zod": "^4.0.0",
44
- "@zhin.js/adapter": "^1.1.12",
45
- "@zhin.js/agent": "^1.1.23",
46
- "@zhin.js/command": "^1.1.0",
47
- "@zhin.js/core": "^1.1.35",
48
- "@zhin.js/permission": "^1.1.0",
49
- "zhin.js": "^1.1.0"
47
+ "@zhin.js/adapter": "^1.1.14",
48
+ "@zhin.js/command": "^1.1.1",
49
+ "@zhin.js/core": "^1.1.37",
50
+ "@zhin.js/permission": "^1.1.1",
51
+ "zhin.js": "^1.1.2"
50
52
  },
51
53
  "peerDependenciesMeta": {
52
- "@zhin.js/agent": {
53
- "optional": true
54
- },
55
54
  "@zhin.js/command": {
56
55
  "optional": true
57
56
  },
@@ -67,9 +66,8 @@
67
66
  "typescript": "^6.0.3",
68
67
  "vitest": "^4.1.10",
69
68
  "zod": "^4.4.3",
70
- "@zhin.js/agent": "1.1.23",
71
- "@zhin.js/host-http": "1.1.0",
72
- "zhin.js": "1.1.0"
69
+ "@zhin.js/host-http": "1.1.1",
70
+ "zhin.js": "1.1.2"
73
71
  },
74
72
  "files": [
75
73
  "adapters",
@@ -78,9 +76,11 @@
78
76
  "schema.json",
79
77
  "src",
80
78
  "lib",
81
- "agent",
79
+ "tools",
80
+ "agents",
82
81
  "README.md",
83
- "CHANGELOG.md"
82
+ "CHANGELOG.md",
83
+ "PERMITS.md"
84
84
  ],
85
85
  "publishConfig": {
86
86
  "access": "public",
@@ -103,6 +103,18 @@
103
103
  {
104
104
  "package": "@zhin.js/command",
105
105
  "api": "^1.0.0"
106
+ },
107
+ {
108
+ "package": "@zhin.js/tool",
109
+ "api": "^1.0.0"
110
+ },
111
+ {
112
+ "package": "@zhin.js/skill",
113
+ "api": "^1.0.0"
114
+ },
115
+ {
116
+ "package": "@zhin.js/agent-feature",
117
+ "api": "^1.0.0"
106
118
  }
107
119
  ],
108
120
  "plugins": []
package/schema.json CHANGED
@@ -60,10 +60,11 @@
60
60
  },
61
61
  "endpoints": {
62
62
  "type": "array",
63
+ "minItems": 1,
63
64
  "description": "多账号:一个插件实例挂多个 endpoint。每项与顶层字段同构(id 必填,其余覆盖顶层)",
64
65
  "items": {
65
66
  "type": "object",
66
- "additionalProperties": true,
67
+ "additionalProperties": false,
67
68
  "properties": {
68
69
  "master": {
69
70
  "type": [
@@ -87,6 +88,36 @@
87
88
  "type": "string",
88
89
  "description": "Telegram bot token"
89
90
  },
91
+ "polling": {
92
+ "type": "boolean"
93
+ },
94
+ "webhook": {
95
+ "type": "object",
96
+ "additionalProperties": false,
97
+ "properties": {
98
+ "domain": {
99
+ "type": "string"
100
+ },
101
+ "path": {
102
+ "type": "string"
103
+ },
104
+ "secretToken": {
105
+ "type": "string"
106
+ }
107
+ }
108
+ },
109
+ "allowedUpdates": {
110
+ "type": "array",
111
+ "items": {
112
+ "type": "string"
113
+ }
114
+ },
115
+ "apiBaseUrl": {
116
+ "type": "string"
117
+ },
118
+ "commandPrefix": {
119
+ "type": "string"
120
+ },
90
121
  "id": {
91
122
  "type": "string",
92
123
  "description": "Telegram bot name"
package/src/index.ts CHANGED
@@ -16,7 +16,7 @@ export {
16
16
  resolveTelegramConfig,
17
17
  senderDisplayName,
18
18
  type ResolvedTelegramConfig,
19
- type TelegramAdapterConfig,
19
+ type TelegramEndpointConfig,
20
20
  type TelegramCallbackQuery,
21
21
  type TelegramChat,
22
22
  type TelegramChatMember,
package/src/protocol.ts CHANGED
@@ -4,18 +4,17 @@
4
4
  */
5
5
 
6
6
  import type { IncomingMessage } from 'node:http';
7
- import { isMediaRef } from '@zhin.js/core';
7
+ import { isMediaRef, type ConversationKind, type ConversationRef } from '@zhin.js/im-contract';
8
8
  import type { Segment } from '@zhin.js/core/runtime';
9
- import type { ConversationKind, ConversationRef } from '@zhin.js/im-contract';
10
9
  import { formatCompact, getLogger } from '@zhin.js/logger';
11
10
  import { escapeTelegramHtml, markdownToTelegramHtml } from './markdown-to-html.js';
12
11
 
13
12
  const logger = getLogger('telegram');
14
13
 
15
- /** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
16
- export interface TelegramAdapterConfig {
17
- readonly id?: string;
18
- readonly token?: string;
14
+ /** One endpoint config after AdapterIndex expands `plugins.<instanceKey>.endpoints`. */
15
+ export interface TelegramEndpointConfig {
16
+ readonly id: string;
17
+ readonly token: string;
19
18
  /** Default true. `false` selects webhook mode (requires httpHostToken). */
20
19
  readonly polling?: boolean;
21
20
  readonly webhook?: {
@@ -25,14 +24,6 @@ export interface TelegramAdapterConfig {
25
24
  };
26
25
  readonly allowedUpdates?: readonly string[];
27
26
  readonly apiBaseUrl?: string;
28
- /** Transitional: legacy root `endpoints[]` with `context: telegram`. */
29
- readonly endpoints?: ReadonlyArray<Partial<ResolvedTelegramConfig> & {
30
- readonly context?: string;
31
- readonly polling?: boolean;
32
- readonly webhook?: TelegramAdapterConfig['webhook'];
33
- readonly allowedUpdates?: readonly string[];
34
- readonly apiBaseUrl?: string;
35
- }>;
36
27
  }
37
28
 
38
29
  export interface ResolvedTelegramConfig {
@@ -246,40 +237,19 @@ export type TelegramOutboundAction =
246
237
  };
247
238
  };
248
239
 
249
- export function resolveTelegramConfig(config: TelegramAdapterConfig = {}): ResolvedTelegramConfig {
250
- const entry = config.endpoints?.find((item) => item.context === 'telegram');
251
- const token = config.token
252
- ?? entry?.token
253
- ?? process.env.TELEGRAM_TOKEN
254
- ?? process.env.TELEGRAM_BOT_TOKEN;
255
- if (!token) {
256
- throw new TypeError(
257
- 'Telegram adapter requires token (plugins.<key>.token or endpoints with context: telegram)',
258
- );
259
- }
260
- const id = (typeof config.id === 'string' && config.id)
261
- || (typeof entry?.id === 'string' && entry.id)
262
- || process.env.TELEGRAM_BOT_NAME
263
- || 'telegram-bot';
264
- const polling = config.polling ?? entry?.polling;
265
- const webhookSource = config.webhook ?? entry?.webhook;
266
- // Match legacy: polling defaults true; webhook only when polling === false.
240
+ export function resolveTelegramConfig(config: TelegramEndpointConfig): ResolvedTelegramConfig {
241
+ const id = requiredEndpointField(config.id, 'id');
242
+ const token = requiredEndpointField(config.token, 'token');
243
+ const polling = config.polling;
244
+ const webhookSource = config.webhook;
267
245
  const mode: 'polling' | 'webhook' = polling === false ? 'webhook' : 'polling';
268
- const apiBaseUrl = (
269
- config.apiBaseUrl
270
- ?? entry?.apiBaseUrl
271
- ?? 'https://api.telegram.org'
272
- ).replace(/\/$/, '');
273
- const allowedUpdates = config.allowedUpdates
274
- ?? entry?.allowedUpdates
275
- ?? ['message', 'callback_query'];
246
+ const apiBaseUrl = (config.apiBaseUrl ?? 'https://api.telegram.org').replace(/\/$/, '');
247
+ const allowedUpdates = config.allowedUpdates ?? ['message', 'callback_query'];
276
248
  const webhook = mode === 'webhook'
277
249
  ? {
278
250
  domain: webhookSource?.domain ?? '',
279
251
  path: normalizeWebhookPath(webhookSource?.path ?? '/telegram/webhook'),
280
- secretToken: webhookSource?.secretToken
281
- ?? process.env.TELEGRAM_WEBHOOK_SECRET
282
- ?? undefined,
252
+ secretToken: webhookSource?.secretToken,
283
253
  }
284
254
  : undefined;
285
255
  return {
@@ -293,6 +263,13 @@ export function resolveTelegramConfig(config: TelegramAdapterConfig = {}): Resol
293
263
  };
294
264
  }
295
265
 
266
+ function requiredEndpointField(value: unknown, field: 'id' | 'token'): string {
267
+ if (typeof value !== 'string' || !value.trim()) {
268
+ throw new TypeError(`Telegram endpoint requires a non-empty ${field}`);
269
+ }
270
+ return value.trim();
271
+ }
272
+
296
273
  export function normalizeWebhookPath(path: string): string {
297
274
  const trimmed = path.trim() || '/telegram/webhook';
298
275
  return trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Telegram 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
3
- * 由 plugin.ts setup() provide,adapter create 与 `telegram.endpoint` 命令共享(同一 owner generation)。
3
+ * 由 plugin.ts setup() provide,adapter create 与 `telegram endpoint` 命令共享(同一 owner generation)。
4
4
  */
5
5
  import { defineEndpointRuntimeStateToken } from 'zhin.js/adapter';
6
6
 
@@ -1,103 +0,0 @@
1
- ---
2
- name: telegram
3
- platforms:
4
- - telegram
5
- description: >-
6
- Telegram 群组全功能管理。当用户在 Telegram 群中请求群管(踢人、封禁、解封、禁言、
7
- 设管理员、改群名/描述)、消息管理(置顶/取消置顶)、社交互动(投票、表情反应、贴纸)、
8
- 或群权限设置时使用。即使用户没有提到 Telegram,只要上下文是 Telegram 群组场景
9
- 且涉及上述操作,就应触发。仅有用户名时必须先查成员列表获取 user_id。
10
- keywords:
11
- - telegram
12
- - tg
13
- - adapter:telegram
14
- - 群管理
15
- - 置顶
16
- - 投票
17
- - 反应
18
- - 贴纸
19
- - 权限
20
- - 封禁
21
- - 禁言
22
- - list_members
23
- tags:
24
- - group
25
- - management
26
- - im
27
- tools:
28
- - telegram_pin_message
29
- - telegram_unpin_message
30
- - telegram_list_admins
31
- - telegram_member_count
32
- - telegram_create_invite
33
- - telegram_send_poll
34
- - telegram_react
35
- - telegram_send_sticker
36
- - telegram_set_permissions
37
- - telegram_set_description
38
- - telegram_kick_member
39
- - telegram_unban_member
40
- - telegram_mute_member
41
- - telegram_set_admin
42
- - telegram_set_group_name
43
- - telegram_get_group_info
44
- ---
45
-
46
- # Telegram 群组管理技能
47
-
48
- Telegram 的群组管理模型与 QQ 不同:没有「群名片」概念,有封禁(ban)/解封(unban)机制,权限体系更细粒度。
49
-
50
- ## 核心原则
51
-
52
- ### 先查后操作
53
-
54
- Telegram 的 user_id 是纯数字,用户通常只知道用户名(@xxx)。操作具体成员前,用 `telegram_list_admins` 或从消息上下文获取 user_id。
55
-
56
- ### Telegram 权限模型
57
-
58
- Telegram 的权限不是简单的 owner/admin/member 三级,而是细粒度的权限集合。通过 `telegram_set_permissions` 可以控制:发消息、发媒体、发投票、添加成员、置顶消息等。
59
-
60
- ## 工具分类
61
-
62
- ### 群管基础
63
-
64
- | 工具 | 用途 | 说明 |
65
- |------|------|------|
66
- | `telegram_kick_member` | 踢出成员 | 踢出后用户仍可重新加入 |
67
- | `telegram_unban_member` | 解除封禁 | 被 ban 的用户无法加入群组 |
68
- | `telegram_mute_member` | 禁言 | duration 单位秒,**0=永久限制** |
69
- | `telegram_set_admin` | 设/取消管理员 | — |
70
- | `telegram_set_group_name` | 改群名 | — |
71
- | `telegram_set_description` | 设群描述 | — |
72
- | `telegram_set_permissions` | 设群权限 | 影响所有普通成员,管理员不受限 |
73
- | `telegram_get_group_info` | 群信息 | — |
74
- | `telegram_list_admins` | 管理员列表 | — |
75
- | `telegram_member_count` | 成员数量 | — |
76
-
77
- ### 消息与社交
78
-
79
- | 工具 | 用途 | 说明 |
80
- |------|------|------|
81
- | `telegram_pin_message` | 置顶消息 | 需管理员权限 |
82
- | `telegram_unpin_message` | 取消置顶 | — |
83
- | `telegram_create_invite` | 创建邀请链接 | 需管理员权限 |
84
- | `telegram_send_poll` | 发起投票 | 支持匿名 + 多选 |
85
- | `telegram_react` | 表情反应 | 对消息贴 emoji |
86
- | `telegram_send_sticker` | 发贴纸 | — |
87
-
88
- ## 与 QQ 群管的关键差异
89
-
90
- | 概念 | QQ(OneBot11) | Telegram |
91
- |------|---------------|----------|
92
- | 禁言 duration=0 | **解禁** | **永久限制** |
93
- | 踢出 | 踢出 = 移除 | 踢出 ≠ 封禁,可重新加入 |
94
- | 封禁 | 无独立概念 | `ban` 阻止加入 |
95
- | 群名片 | 支持 | 不支持 |
96
- | 群权限 | admin/member 二分 | 细粒度权限集 |
97
-
98
- ## 易错点
99
-
100
- 1. **禁言 duration=0 在 Telegram 是永久限制**,与 QQ 的「解禁」含义相反。
101
- 2. **踢人不等于封禁**:`kick_member` 移除但不阻止重新加入;要永久禁止需要 ban。
102
- 3. **投票支持匿名和多选**:用户说「发个投票」时确认是否需要匿名/多选。
103
- 4. **权限设置影响全体普通成员**,不是针对个人。管理员不受影响。
@@ -1,3 +0,0 @@
1
- import { telegramEndpointCommands } from '../../../src/telegram-endpoint-commands.js';
2
-
3
- export default telegramEndpointCommands.add;
@@ -1,3 +0,0 @@
1
- import { telegramEndpointCommands } from '../../src/telegram-endpoint-commands.js';
2
-
3
- export default telegramEndpointCommands.list;
@@ -1,3 +0,0 @@
1
- import { telegramEndpointCommands } from '../../../src/telegram-endpoint-commands.js';
2
-
3
- export default telegramEndpointCommands.remove;
@@ -1 +0,0 @@
1
- export declare const telegramEndpointCommands: import("@zhin.js/adapter").EndpointCommands<Readonly<import("@zhin.js/command").CommandDefinition<unknown, unknown, import("@zhin.js/command").CommandMessage, string | undefined>>>;
File without changes