@shuyhere/takotako 0.0.1 → 0.0.21
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 +198 -27
- package/dist/auth/allow-from.d.ts +20 -0
- package/dist/auth/allow-from.d.ts.map +1 -1
- package/dist/auth/allow-from.js +30 -0
- package/dist/auth/allow-from.js.map +1 -1
- package/dist/channels/channel.d.ts +6 -0
- package/dist/channels/channel.d.ts.map +1 -1
- package/dist/channels/discord.d.ts.map +1 -1
- package/dist/channels/discord.js +31 -7
- package/dist/channels/discord.js.map +1 -1
- package/dist/channels/telegram.d.ts +1 -0
- package/dist/channels/telegram.d.ts.map +1 -1
- package/dist/channels/telegram.js +3 -0
- package/dist/channels/telegram.js.map +1 -1
- package/dist/commands/registry.d.ts.map +1 -1
- package/dist/commands/registry.js +40 -0
- package/dist/commands/registry.js.map +1 -1
- package/dist/core/agent-loop.d.ts.map +1 -1
- package/dist/core/agent-loop.js +456 -441
- package/dist/core/agent-loop.js.map +1 -1
- package/dist/core/message-queue.d.ts.map +1 -1
- package/dist/core/message-queue.js +19 -9
- package/dist/core/message-queue.js.map +1 -1
- package/dist/core/prompt.d.ts.map +1 -1
- package/dist/core/prompt.js +3 -1
- package/dist/core/prompt.js.map +1 -1
- package/dist/core/reactions.d.ts +5 -5
- package/dist/core/reactions.js +10 -10
- package/dist/core/reactions.js.map +1 -1
- package/dist/core/retry-queue.d.ts +2 -0
- package/dist/core/retry-queue.d.ts.map +1 -1
- package/dist/core/retry-queue.js +15 -0
- package/dist/core/retry-queue.js.map +1 -1
- package/dist/gateway/compaction.d.ts +1 -0
- package/dist/gateway/compaction.d.ts.map +1 -1
- package/dist/gateway/compaction.js +5 -1
- package/dist/gateway/compaction.js.map +1 -1
- package/dist/gateway/gateway.d.ts.map +1 -1
- package/dist/gateway/gateway.js +5 -3
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/session.d.ts.map +1 -1
- package/dist/gateway/session.js +7 -0
- package/dist/gateway/session.js.map +1 -1
- package/dist/index.js +91 -16
- package/dist/index.js.map +1 -1
- package/dist/providers/failover.d.ts.map +1 -1
- package/dist/providers/failover.js +8 -7
- package/dist/providers/failover.js.map +1 -1
- package/dist/tools/message.d.ts +10 -0
- package/dist/tools/message.d.ts.map +1 -1
- package/dist/tools/message.js +61 -13
- package/dist/tools/message.js.map +1 -1
- package/dist/tools/system-tools.d.ts.map +1 -1
- package/dist/tools/system-tools.js +26 -1
- package/dist/tools/system-tools.js.map +1 -1
- package/docs/INSTALL.md +7 -4
- package/docs/channels.md +56 -115
- package/package.json +1 -1
package/dist/tools/message.d.ts
CHANGED
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
*
|
|
10
10
|
* This is the tool for all messaging and channel management operations.
|
|
11
11
|
* Do NOT confuse with skill-creator (which creates skills) or agents_add (which creates agents).
|
|
12
|
+
*
|
|
13
|
+
* Target resolution:
|
|
14
|
+
* - Pass "current" (or omit target) on a "send" action to reply in the
|
|
15
|
+
* same channel/chat the agent is currently active in. The channel ID
|
|
16
|
+
* is resolved from the session's ToolContext (ctx.channelTarget).
|
|
12
17
|
*/
|
|
13
18
|
import type { Tool } from './tool.js';
|
|
14
19
|
import type { DiscordChannel } from '../channels/discord.js';
|
|
@@ -16,9 +21,14 @@ import type { TelegramChannel } from '../channels/telegram.js';
|
|
|
16
21
|
export interface MessageToolDeps {
|
|
17
22
|
discord?: DiscordChannel;
|
|
18
23
|
telegram?: TelegramChannel;
|
|
24
|
+
/** Resolve the correct Discord channel for a given agentId at call time. */
|
|
25
|
+
resolveDiscord?: (agentId?: string) => DiscordChannel | undefined;
|
|
26
|
+
/** Resolve the correct Telegram channel for a given agentId at call time. */
|
|
27
|
+
resolveTelegram?: (agentId?: string) => TelegramChannel | undefined;
|
|
19
28
|
}
|
|
20
29
|
/**
|
|
21
30
|
* Create the message tool bound to channel adapters.
|
|
31
|
+
* Supports per-agent channel resolution via resolveDiscord/resolveTelegram.
|
|
22
32
|
*/
|
|
23
33
|
export declare function createMessageTools(deps: MessageToolDeps): Tool[];
|
|
24
34
|
//# sourceMappingURL=message.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/tools/message.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/tools/message.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,WAAW,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,4EAA4E;IAC5E,cAAc,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,cAAc,GAAG,SAAS,CAAC;IAClE,6EAA6E;IAC7E,eAAe,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,eAAe,GAAG,SAAS,CAAC;CACrE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,EAAE,CA+PhE"}
|
package/dist/tools/message.js
CHANGED
|
@@ -9,12 +9,23 @@
|
|
|
9
9
|
*
|
|
10
10
|
* This is the tool for all messaging and channel management operations.
|
|
11
11
|
* Do NOT confuse with skill-creator (which creates skills) or agents_add (which creates agents).
|
|
12
|
+
*
|
|
13
|
+
* Target resolution:
|
|
14
|
+
* - Pass "current" (or omit target) on a "send" action to reply in the
|
|
15
|
+
* same channel/chat the agent is currently active in. The channel ID
|
|
16
|
+
* is resolved from the session's ToolContext (ctx.channelTarget).
|
|
12
17
|
*/
|
|
18
|
+
import { readFile } from 'node:fs/promises';
|
|
19
|
+
import { basename } from 'node:path';
|
|
13
20
|
/**
|
|
14
21
|
* Create the message tool bound to channel adapters.
|
|
22
|
+
* Supports per-agent channel resolution via resolveDiscord/resolveTelegram.
|
|
15
23
|
*/
|
|
16
24
|
export function createMessageTools(deps) {
|
|
17
|
-
const {
|
|
25
|
+
const { resolveDiscord, resolveTelegram } = deps;
|
|
26
|
+
// Fallback to static channels if resolvers not provided
|
|
27
|
+
const getDiscord = (agentId) => resolveDiscord ? resolveDiscord(agentId) : deps.discord;
|
|
28
|
+
const getTelegram = (agentId) => resolveTelegram ? resolveTelegram(agentId) : deps.telegram;
|
|
18
29
|
const messageTool = {
|
|
19
30
|
name: 'message',
|
|
20
31
|
description: 'Send messages and manage channels on Discord and Telegram. Use this for all messaging operations: sending messages, creating/editing/deleting Discord channels, creating threads, and reacting to messages. This is NOT for creating agents (use agents_add) or skills (use skill-creator).',
|
|
@@ -41,12 +52,16 @@ export function createMessageTools(deps) {
|
|
|
41
52
|
},
|
|
42
53
|
target: {
|
|
43
54
|
type: 'string',
|
|
44
|
-
description: 'Channel ID, chat ID, or guild ID (depends on action)',
|
|
55
|
+
description: 'Channel ID, chat ID, or guild ID (depends on action). Use "current" to send to the channel this agent is currently active in.',
|
|
45
56
|
},
|
|
46
57
|
message: {
|
|
47
58
|
type: 'string',
|
|
48
59
|
description: 'Message content to send (for "send" action)',
|
|
49
60
|
},
|
|
61
|
+
media: {
|
|
62
|
+
type: 'string',
|
|
63
|
+
description: 'Optional media path or URL to attach (Discord send only)',
|
|
64
|
+
},
|
|
50
65
|
name: {
|
|
51
66
|
type: 'string',
|
|
52
67
|
description: 'Name for new channel or thread (for "channel-create" and "thread-create")',
|
|
@@ -74,34 +89,67 @@ export function createMessageTools(deps) {
|
|
|
74
89
|
},
|
|
75
90
|
required: ['action', 'platform'],
|
|
76
91
|
},
|
|
77
|
-
async execute(params,
|
|
92
|
+
async execute(params, ctx) {
|
|
78
93
|
const p = params;
|
|
94
|
+
// Resolve "current" target → use the session's active channel
|
|
95
|
+
const resolveTarget = (t) => {
|
|
96
|
+
if (!t || t === 'current')
|
|
97
|
+
return ctx.channelTarget;
|
|
98
|
+
return t;
|
|
99
|
+
};
|
|
100
|
+
// Resolve per-agent channels at call time using ctx.agentId
|
|
101
|
+
const discord = getDiscord(ctx.agentId);
|
|
102
|
+
const telegram = getTelegram(ctx.agentId);
|
|
79
103
|
// Validate platform availability
|
|
80
104
|
if (p.platform === 'discord' && !discord) {
|
|
81
|
-
return { output: '', success: false, error: 'Discord channel is not configured or connected.' };
|
|
105
|
+
return { output: '', success: false, error: 'Discord channel is not configured or connected for this agent.' };
|
|
82
106
|
}
|
|
83
107
|
if (p.platform === 'telegram' && !telegram) {
|
|
84
|
-
return { output: '', success: false, error: 'Telegram channel is not configured or connected.' };
|
|
108
|
+
return { output: '', success: false, error: 'Telegram channel is not configured or connected for this agent.' };
|
|
85
109
|
}
|
|
86
110
|
try {
|
|
87
111
|
switch (p.action) {
|
|
88
112
|
// ─── send ──────────────────────────────────────────────
|
|
89
113
|
case 'send': {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
114
|
+
const target = resolveTarget(p.target);
|
|
115
|
+
if (!target)
|
|
116
|
+
return { output: '', success: false, error: 'target (channel/chat ID) is required for send — or use "current" to send to the active channel' };
|
|
117
|
+
if (!p.message && !p.media)
|
|
118
|
+
return { output: '', success: false, error: 'message or media is required for send' };
|
|
94
119
|
if (p.platform === 'discord') {
|
|
95
|
-
|
|
120
|
+
if (p.media) {
|
|
121
|
+
const isUrl = /^https?:\/\//i.test(p.media);
|
|
122
|
+
const attachments = [];
|
|
123
|
+
if (isUrl) {
|
|
124
|
+
attachments.push({ type: 'file', url: p.media, filename: basename(new URL(p.media).pathname) || 'attachment' });
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
const data = await readFile(p.media);
|
|
128
|
+
attachments.push({ type: 'file', data, filename: basename(p.media) || 'attachment' });
|
|
129
|
+
}
|
|
130
|
+
const msgId = await discord.sendAndGetId({
|
|
131
|
+
target,
|
|
132
|
+
content: p.message ?? '',
|
|
133
|
+
attachments,
|
|
134
|
+
});
|
|
135
|
+
return {
|
|
136
|
+
output: JSON.stringify({ sent: true, platform: 'discord', channelId: target, messageId: msgId, attached: true, agentId: ctx.agentId }),
|
|
137
|
+
success: true,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
const msgId = await discord.sendToChannel(target, p.message ?? '');
|
|
96
141
|
return {
|
|
97
|
-
output: JSON.stringify({ sent: true, platform: 'discord', channelId:
|
|
142
|
+
output: JSON.stringify({ sent: true, platform: 'discord', channelId: target, messageId: msgId, agentId: ctx.agentId }),
|
|
98
143
|
success: true,
|
|
99
144
|
};
|
|
100
145
|
}
|
|
101
146
|
else {
|
|
102
|
-
|
|
147
|
+
if (p.media) {
|
|
148
|
+
return { output: '', success: false, error: 'media attachments are currently supported for Discord only' };
|
|
149
|
+
}
|
|
150
|
+
const msgId = await telegram.sendToChat(target, p.message ?? '');
|
|
103
151
|
return {
|
|
104
|
-
output: JSON.stringify({ sent: true, platform: 'telegram', chatId:
|
|
152
|
+
output: JSON.stringify({ sent: true, platform: 'telegram', chatId: target, messageId: msgId, agentId: ctx.agentId }),
|
|
105
153
|
success: true,
|
|
106
154
|
};
|
|
107
155
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../src/tools/message.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../src/tools/message.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-tools.d.ts","sourceRoot":"","sources":["../../src/tools/system-tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"system-tools.d.ts","sourceRoot":"","sources":["../../src/tools/system-tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAKlD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAoDpH"}
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Allows the agent to restart itself and deliver a post-restart note.
|
|
5
5
|
*/
|
|
6
|
+
import { homedir } from 'node:os';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
9
|
+
import { existsSync } from 'node:fs';
|
|
10
|
+
const RESTART_GUARD_PATH = join(homedir(), '.tako', 'restart-guard.json');
|
|
11
|
+
const MIN_RESTART_INTERVAL_MS = 90_000;
|
|
6
12
|
export function registerSystemTools(registry, opts) {
|
|
7
13
|
registry.register({
|
|
8
14
|
name: 'system_restart',
|
|
@@ -19,11 +25,30 @@ export function registerSystemTools(registry, opts) {
|
|
|
19
25
|
execute: async (_args, ctx) => {
|
|
20
26
|
const note = _args.note || 'Tako restarted.';
|
|
21
27
|
const sessionKey = ctx.sessionId || null;
|
|
28
|
+
const channelId = ctx.channelTarget || null;
|
|
29
|
+
const agentId = ctx.agentId || null;
|
|
22
30
|
try {
|
|
31
|
+
// Guard against restart loops caused by repeated tool calls.
|
|
32
|
+
try {
|
|
33
|
+
if (existsSync(RESTART_GUARD_PATH)) {
|
|
34
|
+
const raw = await readFile(RESTART_GUARD_PATH, 'utf-8');
|
|
35
|
+
const parsed = JSON.parse(raw);
|
|
36
|
+
const last = parsed.lastRestartAt ?? 0;
|
|
37
|
+
const elapsed = Date.now() - last;
|
|
38
|
+
if (elapsed < MIN_RESTART_INTERVAL_MS) {
|
|
39
|
+
const wait = Math.ceil((MIN_RESTART_INTERVAL_MS - elapsed) / 1000);
|
|
40
|
+
return { success: false, output: `Restart blocked by safety guard. Try again in ~${wait}s.` };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Ignore malformed guard file.
|
|
46
|
+
}
|
|
47
|
+
await writeFile(RESTART_GUARD_PATH, JSON.stringify({ lastRestartAt: Date.now() }) + '\n', { mode: 0o600 });
|
|
23
48
|
const res = await fetch(`http://${opts.gatewayBind}:${opts.gatewayPort}/restart`, {
|
|
24
49
|
method: 'POST',
|
|
25
50
|
headers: { 'Content-Type': 'application/json' },
|
|
26
|
-
body: JSON.stringify({ note, sessionKey }),
|
|
51
|
+
body: JSON.stringify({ note, sessionKey, channelId, agentId }),
|
|
27
52
|
});
|
|
28
53
|
if (res.ok) {
|
|
29
54
|
return { success: true, output: `Restart initiated. Note "${note}" will be delivered after restart.` };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-tools.js","sourceRoot":"","sources":["../../src/tools/system-tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"system-tools.js","sourceRoot":"","sources":["../../src/tools/system-tools.ts"],"names":[],"mappings":"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"}
|
package/docs/INSTALL.md
CHANGED
|
@@ -4,9 +4,9 @@ This guide covers production and local installation for Tako.
|
|
|
4
4
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
7
|
-
- Node.js >= 20
|
|
8
|
-
- npm >= 9
|
|
9
|
-
-
|
|
7
|
+
- Node.js >= 20 (required)
|
|
8
|
+
- npm >= 9 (required)
|
|
9
|
+
- Bun >= 1.0 (recommended; required for Bun-based commands)
|
|
10
10
|
- Git
|
|
11
11
|
|
|
12
12
|
## 0) Environment setup (for users)
|
|
@@ -44,6 +44,8 @@ git --version
|
|
|
44
44
|
|
|
45
45
|
## 1) Install package
|
|
46
46
|
|
|
47
|
+
Published package: `@shuyhere/takotako`
|
|
48
|
+
|
|
47
49
|
### npm
|
|
48
50
|
|
|
49
51
|
```bash
|
|
@@ -66,6 +68,7 @@ Verify:
|
|
|
66
68
|
|
|
67
69
|
```bash
|
|
68
70
|
tako --help
|
|
71
|
+
npm view @shuyhere/takotako version
|
|
69
72
|
```
|
|
70
73
|
|
|
71
74
|
## 2) First-time setup
|
|
@@ -138,7 +141,7 @@ tako status
|
|
|
138
141
|
|
|
139
142
|
```bash
|
|
140
143
|
npm install -g @shuyhere/takotako
|
|
141
|
-
# or
|
|
144
|
+
# or GitHub source fallback:
|
|
142
145
|
# npm install -g github:shuyhere/tako
|
|
143
146
|
```
|
|
144
147
|
|
package/docs/channels.md
CHANGED
|
@@ -1,140 +1,81 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Channel Setup — Getting Your Bot Tokens
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Tako connects to Discord and Telegram through bot tokens. This guide explains how to get those tokens. Once you have them, just run `tako onboard` and paste them in when prompted.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Discord
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
```
|
|
9
|
+
### Step 1 — Create a Discord application
|
|
10
|
+
|
|
11
|
+
1. Go to [https://discord.com/developers/applications](https://discord.com/developers/applications)
|
|
12
|
+
2. Click **New Application** → give it a name (e.g. `Tako`)
|
|
13
|
+
3. Go to the **Bot** tab → click **Add Bot**
|
|
14
|
+
4. Under **Token**, click **Reset Token** → **copy it** (you'll need this in `tako onboard`)
|
|
15
|
+
|
|
16
|
+
### Step 2 — Enable required intents
|
|
19
17
|
|
|
20
|
-
**
|
|
21
|
-
- Streaming output (chunks written to stdout in real-time)
|
|
22
|
-
- `/quit` and `/exit` commands to stop
|
|
23
|
-
- Serialized message handling (no overlapping executions)
|
|
18
|
+
Still on the **Bot** tab, scroll down to **Privileged Gateway Intents** and enable:
|
|
24
19
|
|
|
25
|
-
|
|
20
|
+
- ✅ `MESSAGE CONTENT INTENT` — required to read messages
|
|
21
|
+
- ✅ `SERVER MEMBERS INTENT` — optional, for member info
|
|
26
22
|
|
|
27
|
-
|
|
23
|
+
### Step 3 — Invite the bot to your server
|
|
24
|
+
|
|
25
|
+
1. Go to **OAuth2 → URL Generator**
|
|
26
|
+
2. Under **Scopes**, check: `bot` and `applications.commands`
|
|
27
|
+
3. Under **Bot Permissions**, check:
|
|
28
|
+
- Send Messages
|
|
29
|
+
- Read Messages / View Channels
|
|
30
|
+
- Read Message History
|
|
31
|
+
- Add Reactions
|
|
32
|
+
- Attach Files
|
|
33
|
+
- Embed Links
|
|
34
|
+
- Create Public Threads
|
|
35
|
+
- Send Messages in Threads
|
|
36
|
+
- Manage Channels
|
|
37
|
+
- Use Slash Commands
|
|
38
|
+
4. Copy the generated URL → open it in your browser → select your server → **Authorize**
|
|
39
|
+
|
|
40
|
+
### Step 4 — Run onboarding
|
|
28
41
|
|
|
29
|
-
**Launch:**
|
|
30
42
|
```bash
|
|
31
|
-
tako
|
|
43
|
+
tako onboard
|
|
32
44
|
```
|
|
33
45
|
|
|
34
|
-
|
|
35
|
-
- Real-time streaming output
|
|
36
|
-
- Image attachment support
|
|
37
|
-
- Tab-completion for commands
|
|
38
|
-
- Active agent display in header
|
|
39
|
-
- Bot name masking for privacy
|
|
40
|
-
|
|
41
|
-
## Discord (Built-in)
|
|
42
|
-
|
|
43
|
-
Discord bot via discord.js.
|
|
44
|
-
|
|
45
|
-
**Configuration:**
|
|
46
|
-
```json
|
|
47
|
-
{
|
|
48
|
-
"channels": {
|
|
49
|
-
"discord": {
|
|
50
|
-
"token": "your-bot-token",
|
|
51
|
-
"guilds": ["guild-id-1", "guild-id-2"]
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
```
|
|
46
|
+
When prompted for a Discord bot token, paste the token you copied in Step 1.
|
|
56
47
|
|
|
57
|
-
|
|
58
|
-
- Auto-create threads for replies (reference runtime-style)
|
|
59
|
-
- DM support (via Partials.Channel + Partials.Message)
|
|
60
|
-
- Typing indicators (configurable via `agent.typingMode`)
|
|
61
|
-
- Automatic message splitting (Discord's 2000 char limit)
|
|
62
|
-
- Auto-reconnect with exponential backoff (up to 5 attempts)
|
|
63
|
-
- Guild filtering (optional — respond only in specific servers)
|
|
64
|
-
- Attachment extraction (images, files)
|
|
65
|
-
- Sender name shown in messages: `[From: name]`
|
|
66
|
-
|
|
67
|
-
**Setup:**
|
|
68
|
-
1. Create a bot at [Discord Developer Portal](https://discord.com/developers/applications)
|
|
69
|
-
2. Enable Message Content Intent
|
|
70
|
-
3. Invite bot to your server with message permissions
|
|
71
|
-
4. Set the token via `tako onboard` or `tako channels`
|
|
72
|
-
|
|
73
|
-
## Telegram (Built-in)
|
|
74
|
-
|
|
75
|
-
Telegram bot via grammY.
|
|
76
|
-
|
|
77
|
-
**Configuration:**
|
|
78
|
-
```json
|
|
79
|
-
{
|
|
80
|
-
"channels": {
|
|
81
|
-
"telegram": {
|
|
82
|
-
"token": "your-bot-token",
|
|
83
|
-
"allowedUsers": ["username1", "username2"]
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
```
|
|
48
|
+
---
|
|
88
49
|
|
|
89
|
-
|
|
90
|
-
- Long polling (non-blocking)
|
|
91
|
-
- Typing indicators (configurable via `agent.typingMode`)
|
|
92
|
-
- Reactions support
|
|
93
|
-
- Markdown formatting with fallback to plain text
|
|
94
|
-
- Max 4096 chars per message (Telegram limit)
|
|
95
|
-
- User filtering (optional — respond only to specific users)
|
|
96
|
-
- Supports photos, documents, audio, video attachments
|
|
97
|
-
- Sender name shown in messages: `[From: name]`
|
|
50
|
+
## Telegram
|
|
98
51
|
|
|
99
|
-
|
|
100
|
-
1. Create a bot via [@BotFather](https://t.me/BotFather)
|
|
101
|
-
2. Get the token
|
|
102
|
-
3. Set via `tako onboard` or `tako channels`
|
|
52
|
+
### Step 1 — Create a bot with BotFather
|
|
103
53
|
|
|
104
|
-
|
|
54
|
+
1. Open Telegram and search for **@BotFather**
|
|
55
|
+
2. Send `/newbot`
|
|
56
|
+
3. Follow the prompts — choose a name and username for your bot
|
|
57
|
+
4. BotFather will reply with your bot token — **copy it**
|
|
105
58
|
|
|
106
|
-
|
|
59
|
+
### Step 2 — Find your Telegram user ID (for access control)
|
|
107
60
|
|
|
108
|
-
|
|
109
|
-
import type { Channel, OutboundMessage, MessageHandler, InboundMessage } from './channel.js';
|
|
61
|
+
Message **[@userinfobot](https://t.me/userinfobot)** on Telegram. It will reply with your numeric user ID. Keep this handy — `tako onboard` will ask for it to lock the bot to your account.
|
|
110
62
|
|
|
111
|
-
|
|
112
|
-
id = 'my-channel';
|
|
113
|
-
private handler?: MessageHandler;
|
|
63
|
+
### Step 3 — Run onboarding
|
|
114
64
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
65
|
+
```bash
|
|
66
|
+
tako onboard
|
|
67
|
+
```
|
|
118
68
|
|
|
119
|
-
|
|
120
|
-
// Clean up
|
|
121
|
-
}
|
|
69
|
+
When prompted for a Telegram bot token, paste the token from Step 1.
|
|
122
70
|
|
|
123
|
-
|
|
124
|
-
// Send message to your platform
|
|
125
|
-
}
|
|
71
|
+
---
|
|
126
72
|
|
|
127
|
-
|
|
128
|
-
this.handler = handler;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
```
|
|
73
|
+
## Multiple agents
|
|
132
74
|
|
|
133
|
-
|
|
75
|
+
Each agent (e.g. `code-agent`, `project-manager`) can have its own Discord bot. Just create a separate Discord application for each one and configure them via:
|
|
134
76
|
|
|
135
|
-
|
|
77
|
+
```
|
|
78
|
+
/setup
|
|
79
|
+
```
|
|
136
80
|
|
|
137
|
-
|
|
138
|
-
- Sessions are keyed by `channelId:authorId`
|
|
139
|
-
- The agent loop runs per-message, streaming output back through the originating channel
|
|
140
|
-
- CLI streams to stdout; other channels send the complete response
|
|
81
|
+
in Discord after Tako is running. See **[agent use cases in the README](../README.md#creating-agents)** for details.
|