@4via6/relay 1.0.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.
Files changed (99) hide show
  1. package/.env.example +50 -0
  2. package/README.md +253 -0
  3. package/dist/auth.d.ts +3 -0
  4. package/dist/auth.js +32 -0
  5. package/dist/auth.js.map +1 -0
  6. package/dist/bot.d.ts +2 -0
  7. package/dist/bot.js +14 -0
  8. package/dist/bot.js.map +1 -0
  9. package/dist/cli.d.ts +2 -0
  10. package/dist/cli.js +3 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/commands/admin.d.ts +2 -0
  13. package/dist/commands/admin.js +420 -0
  14. package/dist/commands/admin.js.map +1 -0
  15. package/dist/commands/chat.d.ts +2 -0
  16. package/dist/commands/chat.js +80 -0
  17. package/dist/commands/chat.js.map +1 -0
  18. package/dist/commands/files.d.ts +2 -0
  19. package/dist/commands/files.js +162 -0
  20. package/dist/commands/files.js.map +1 -0
  21. package/dist/commands/history.d.ts +2 -0
  22. package/dist/commands/history.js +152 -0
  23. package/dist/commands/history.js.map +1 -0
  24. package/dist/commands/index.d.ts +2 -0
  25. package/dist/commands/index.js +21 -0
  26. package/dist/commands/index.js.map +1 -0
  27. package/dist/commands/mcp.d.ts +2 -0
  28. package/dist/commands/mcp.js +105 -0
  29. package/dist/commands/mcp.js.map +1 -0
  30. package/dist/commands/media.d.ts +2 -0
  31. package/dist/commands/media.js +248 -0
  32. package/dist/commands/media.js.map +1 -0
  33. package/dist/commands/monitor.d.ts +2 -0
  34. package/dist/commands/monitor.js +136 -0
  35. package/dist/commands/monitor.js.map +1 -0
  36. package/dist/commands/session.d.ts +2 -0
  37. package/dist/commands/session.js +114 -0
  38. package/dist/commands/session.js.map +1 -0
  39. package/dist/commands/shell.d.ts +2 -0
  40. package/dist/commands/shell.js +90 -0
  41. package/dist/commands/shell.js.map +1 -0
  42. package/dist/index.d.ts +1 -0
  43. package/dist/index.js +82 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/providers/claude.d.ts +52 -0
  46. package/dist/providers/claude.js +449 -0
  47. package/dist/providers/claude.js.map +1 -0
  48. package/dist/providers/codex.d.ts +45 -0
  49. package/dist/providers/codex.js +400 -0
  50. package/dist/providers/codex.js.map +1 -0
  51. package/dist/providers/index.d.ts +6 -0
  52. package/dist/providers/index.js +40 -0
  53. package/dist/providers/index.js.map +1 -0
  54. package/dist/providers/opencode.d.ts +40 -0
  55. package/dist/providers/opencode.js +498 -0
  56. package/dist/providers/opencode.js.map +1 -0
  57. package/dist/providers/types.d.ts +173 -0
  58. package/dist/providers/types.js +6 -0
  59. package/dist/providers/types.js.map +1 -0
  60. package/dist/session.d.ts +10 -0
  61. package/dist/session.js +65 -0
  62. package/dist/session.js.map +1 -0
  63. package/dist/utils/chunker.d.ts +1 -0
  64. package/dist/utils/chunker.js +24 -0
  65. package/dist/utils/chunker.js.map +1 -0
  66. package/dist/utils/errors.d.ts +12 -0
  67. package/dist/utils/errors.js +85 -0
  68. package/dist/utils/errors.js.map +1 -0
  69. package/dist/utils/files.d.ts +15 -0
  70. package/dist/utils/files.js +81 -0
  71. package/dist/utils/files.js.map +1 -0
  72. package/dist/utils/html.d.ts +4 -0
  73. package/dist/utils/html.js +10 -0
  74. package/dist/utils/html.js.map +1 -0
  75. package/dist/utils/media.d.ts +15 -0
  76. package/dist/utils/media.js +103 -0
  77. package/dist/utils/media.js.map +1 -0
  78. package/dist/utils/store.d.ts +15 -0
  79. package/dist/utils/store.js +44 -0
  80. package/dist/utils/store.js.map +1 -0
  81. package/dist/utils/stream.d.ts +21 -0
  82. package/dist/utils/stream.js +149 -0
  83. package/dist/utils/stream.js.map +1 -0
  84. package/dist/utils/stt.d.ts +7 -0
  85. package/dist/utils/stt.js +118 -0
  86. package/dist/utils/stt.js.map +1 -0
  87. package/dist/utils/system-prompt.d.ts +5 -0
  88. package/dist/utils/system-prompt.js +64 -0
  89. package/dist/utils/system-prompt.js.map +1 -0
  90. package/dist/utils/timeout.d.ts +2 -0
  91. package/dist/utils/timeout.js +18 -0
  92. package/dist/utils/timeout.js.map +1 -0
  93. package/docs/commands.md +351 -0
  94. package/docs/configuration.md +160 -0
  95. package/docs/features.md +443 -0
  96. package/docs/getting-started.md +102 -0
  97. package/docs/providers.md +236 -0
  98. package/docs/troubleshooting.md +287 -0
  99. package/package.json +54 -0
@@ -0,0 +1,443 @@
1
+ # Features
2
+
3
+ Detailed guide to Relay's key features.
4
+
5
+ ---
6
+
7
+ ## Streaming Responses
8
+
9
+ Relay streams AI responses in real time. As the AI generates text, the Telegram message is progressively edited so you see output as it's produced rather than waiting for the full response.
10
+
11
+ ### How it works
12
+
13
+ 1. You send a message
14
+ 2. The bot sends an initial "thinking" indicator
15
+ 3. As text arrives, the message is edited in place with new content
16
+ 4. When the response is complete, the final message is sent
17
+
18
+ ### Streaming behavior
19
+
20
+ - Messages are updated approximately every second to avoid Telegram rate limits
21
+ - Very long responses are split into multiple messages (Telegram's 4096-character limit)
22
+ - Tool use indicators (e.g., "Reading file...", "Running command...") appear during processing
23
+ - If the AI is using tools, you'll see status updates before the final text response
24
+
25
+ ### Configuration
26
+
27
+ Streaming is enabled by default. To disable it:
28
+
29
+ ```env
30
+ STREAMING=false
31
+ ```
32
+
33
+ When disabled, the bot waits for the complete response before sending a single message.
34
+
35
+ ---
36
+
37
+ ## File Attachments
38
+
39
+ When the AI generates files, takes screenshots, or creates artifacts, they are automatically sent as Telegram attachments. This feature is available with the OpenCode provider.
40
+
41
+ ### Supported file types
42
+
43
+ - **Images** (`image/png`, `image/jpeg`, etc.) — sent as Telegram photos
44
+ - **All other files** — sent as Telegram documents with the original filename
45
+
46
+ ### How it works
47
+
48
+ OpenCode returns structured file parts in its responses. Relay extracts these automatically and sends them after the text response. No action is needed from the user.
49
+
50
+ Common scenarios where you receive file attachments:
51
+ - The AI takes a browser screenshot (via MCP browser tool)
52
+ - The AI generates an image or diagram
53
+ - The AI creates a downloadable file
54
+
55
+ ### Provider support
56
+
57
+ | Provider | File output |
58
+ |----------|------------|
59
+ | OpenCode | Yes — automatic |
60
+ | Claude | No |
61
+ | Codex | No |
62
+
63
+ ---
64
+
65
+ ## Voice Messages
66
+
67
+ Send voice notes to the bot and they'll be transcribed and processed as text input.
68
+
69
+ ### Setup
70
+
71
+ Configure at least one speech-to-text provider:
72
+
73
+ ```env
74
+ GROQ_API_KEY=gsk_... # Groq Whisper (fastest, has free tier)
75
+ OPENAI_API_KEY=sk-... # OpenAI Whisper
76
+ ASSEMBLYAI_API_KEY=... # AssemblyAI
77
+ ```
78
+
79
+ If multiple providers are configured, the cheapest available one is selected automatically.
80
+
81
+ ### How it works
82
+
83
+ 1. Record a voice message in Telegram
84
+ 2. The bot downloads the audio file
85
+ 3. The audio is sent to the STT provider for transcription
86
+ 4. The transcribed text is sent to the AI as a regular message
87
+ 5. You receive the AI's response as usual
88
+
89
+ ### Provider priority
90
+
91
+ 1. **Groq** — Fastest, free tier available
92
+ 2. **OpenAI** — Reliable, widely available
93
+ 3. **AssemblyAI** — Alternative option
94
+
95
+ ---
96
+
97
+ ## Photo Input
98
+
99
+ Send photos to the bot for analysis by vision-capable models.
100
+
101
+ ### How it works
102
+
103
+ 1. Send a photo (with or without a caption)
104
+ 2. The bot downloads the image
105
+ 3. The image is sent to the AI model along with any caption text
106
+ 4. The AI analyzes the image and responds
107
+
108
+ ### Tips
109
+
110
+ - Add a caption to your photo to ask specific questions about it (e.g., "What's wrong with this UI?")
111
+ - Without a caption, the AI will describe or analyze the image
112
+ - Vision capability depends on the model — check `/models` for vision badges
113
+
114
+ ---
115
+
116
+ ## File Input
117
+
118
+ Send files to the bot as attachments.
119
+
120
+ ### Text files
121
+
122
+ Text files (`.txt`, `.md`, `.js`, `.py`, `.json`, `.yaml`, `.toml`, `.xml`, `.csv`, `.html`, `.css`, etc.) are read and their content is embedded directly in the message to the AI.
123
+
124
+ ### Binary files
125
+
126
+ Binary files are referenced by name but their content is not sent to the AI. The AI is informed that a file was attached.
127
+
128
+ ### Size limit
129
+
130
+ Text messages have a 32,000-character limit. For larger content, send it as a file attachment.
131
+
132
+ ---
133
+
134
+ ## MCP Servers
135
+
136
+ MCP (Model Context Protocol) servers extend the AI's capabilities with additional tools like browsers, databases, and external APIs.
137
+
138
+ ### Adding a local MCP server
139
+
140
+ Local servers run as subprocesses on the same machine:
141
+
142
+ ```
143
+ /mcp add memory local npx -y @modelcontextprotocol/server-memory
144
+ /mcp add browser local npx -y @anthropic-ai/mcp-server-puppeteer
145
+ /mcp add filesystem local npx -y @modelcontextprotocol/server-filesystem /home/user/projects
146
+ ```
147
+
148
+ ### Adding a remote MCP server
149
+
150
+ Remote servers connect via URL:
151
+
152
+ ```
153
+ /mcp add api remote https://mcp.example.com/sse
154
+ ```
155
+
156
+ ### Checking status
157
+
158
+ Use `/mcp` to see all configured servers and their connection status:
159
+
160
+ ```
161
+ MCP Servers (2)
162
+
163
+ memory ok
164
+ browser failed
165
+ Connection refused
166
+ ```
167
+
168
+ ### Removing a server
169
+
170
+ ```
171
+ /mcp remove browser
172
+ ```
173
+
174
+ ### Provider differences
175
+
176
+ | Feature | OpenCode | Claude | Codex |
177
+ |---------|----------|--------|-------|
178
+ | MCP support | Full API | Persisted to disk | No |
179
+ | Persistence | Saved in config | Saved in `.relay/` | N/A |
180
+ | Local servers | Yes | Yes | No |
181
+ | Remote servers | Yes | Yes | No |
182
+
183
+ **OpenCode** manages MCP servers through its API. Servers persist across restarts.
184
+
185
+ **Claude** stores MCP configs in `.relay/claude-mcp.json`. Servers are automatically restored on restart.
186
+
187
+ **Codex** does not support MCP.
188
+
189
+ ---
190
+
191
+ ## Model Selection
192
+
193
+ Relay supports switching between AI models at runtime.
194
+
195
+ ### Listing available models
196
+
197
+ Use `/models` to see all configured models:
198
+
199
+ ```
200
+ Available Models
201
+
202
+ anthropic
203
+ claude-sonnet-4-20250514 [reasoning] [active]
204
+ claude-opus-4-20250514 [reasoning]
205
+ claude-haiku-4-20250514
206
+
207
+ openrouter
208
+ deepseek/deepseek-r1 [reasoning]
209
+ ```
210
+
211
+ ### Capability badges
212
+
213
+ - `[reasoning]` — The model supports extended thinking/reasoning
214
+ - `[vision]` — The model accepts image input
215
+ - `[active]` — Currently selected model
216
+
217
+ ### Switching models
218
+
219
+ By full path:
220
+ ```
221
+ /model anthropic/claude-sonnet-4-20250514
222
+ ```
223
+
224
+ By partial match:
225
+ ```
226
+ /model sonnet
227
+ /model deepseek
228
+ ```
229
+
230
+ After switching, the bot confirms the model and shows its capabilities:
231
+ ```
232
+ Model set to anthropic/claude-sonnet-4-20250514
233
+ Capabilities: reasoning, vision
234
+ ```
235
+
236
+ ### Provider behavior
237
+
238
+ - **OpenCode**: Lists all models from all configured providers dynamically
239
+ - **Claude**: Fetches available models dynamically from the Anthropic API (`GET /v1/models`)
240
+ - **Codex**: Fetches available models dynamically from the OpenAI API (`GET /v1/models`)
241
+
242
+ ---
243
+
244
+ ## System Prompt
245
+
246
+ Customize the AI's behavior with a system prompt file.
247
+
248
+ ### Default behavior
249
+
250
+ The bot loads a system prompt from `skill.md` in the project root. If the file doesn't exist, a built-in default prompt is used.
251
+
252
+ ### Custom prompt file
253
+
254
+ Set a custom path:
255
+
256
+ ```env
257
+ SYSTEM_PROMPT_FILE=prompts/my-prompt.md
258
+ ```
259
+
260
+ ### Hot reload
261
+
262
+ The system prompt file is watched for changes. When you edit it, the new prompt is loaded automatically on the next message.
263
+
264
+ To force a reload:
265
+ ```
266
+ /system reload
267
+ ```
268
+
269
+ ### Viewing the prompt
270
+
271
+ Use `/system` to see the current prompt (first 500 characters), its source, and character count.
272
+
273
+ ---
274
+
275
+ ## Session Management
276
+
277
+ Sessions keep your conversations organized. Each session maintains its own message history.
278
+
279
+ ### Creating sessions
280
+
281
+ ```
282
+ /new # Create with auto-generated title
283
+ /new Refactoring auth module # Create with a custom title
284
+ ```
285
+
286
+ The new session becomes active immediately.
287
+
288
+ ### Listing sessions
289
+
290
+ ```
291
+ /sessions
292
+ ```
293
+
294
+ Shows all sessions sorted by last modified date, with the active session marked.
295
+
296
+ ### Switching sessions
297
+
298
+ ```
299
+ /switch abc123
300
+ ```
301
+
302
+ ### Forking sessions
303
+
304
+ Create a copy of the current session:
305
+
306
+ ```
307
+ /fork # Fork from the latest message
308
+ /fork msg_abc123 # Fork from a specific message
309
+ ```
310
+
311
+ The forked session becomes the active session. Supported by OpenCode and Claude.
312
+
313
+ ### Deleting sessions
314
+
315
+ ```
316
+ /delete abc123
317
+ ```
318
+
319
+ ---
320
+
321
+ ## Monitoring (OpenCode)
322
+
323
+ ### Todo list
324
+
325
+ View the AI's task checklist:
326
+
327
+ ```
328
+ /todo
329
+ ```
330
+
331
+ Shows tasks with status icons for completed, in progress, pending, and cancelled items.
332
+
333
+ ### Code diffs
334
+
335
+ View a summary of changes:
336
+
337
+ ```
338
+ /diff
339
+ ```
340
+
341
+ Download the full diff:
342
+
343
+ ```
344
+ /diff full
345
+ ```
346
+
347
+ ### Revert and unrevert
348
+
349
+ Undo the last AI change:
350
+
351
+ ```
352
+ /revert
353
+ ```
354
+
355
+ Redo a reverted change:
356
+
357
+ ```
358
+ /unrevert
359
+ ```
360
+
361
+ ---
362
+
363
+ ## Shell Access
364
+
365
+ Run commands on the coding agent's machine:
366
+
367
+ ```
368
+ /shell ls -la
369
+ /shell git log --oneline -5
370
+ /shell npm test
371
+ ```
372
+
373
+ **OpenCode** runs commands natively on the server.
374
+
375
+ **Claude and Codex** send the command as a prompt, asking the AI to execute it. The AI decides whether and how to run it.
376
+
377
+ ---
378
+
379
+ ## State Persistence
380
+
381
+ Relay automatically persists critical state to disk so it survives bot restarts and crashes.
382
+
383
+ ### What is persisted
384
+
385
+ | Data | File | Description |
386
+ |------|------|-------------|
387
+ | Active session | `.relay/session.json` | Current session ID and selected model |
388
+ | Claude MCP servers | `.relay/claude-mcp.json` | MCP server configurations (Claude provider) |
389
+ | Codex thread IDs | `.relay/codex-threads.json` | Thread ID mappings (Codex provider) |
390
+
391
+ ### How it works
392
+
393
+ - State is written atomically (via temp file + rename) to prevent corruption
394
+ - Files are loaded on startup and written immediately on change
395
+ - If a state file is missing or corrupt, the bot starts fresh with defaults
396
+ - The `.relay/` directory is created automatically and excluded from git
397
+
398
+ ### Configuration
399
+
400
+ Override the data directory:
401
+
402
+ ```env
403
+ RELAY_DATA_DIR=/path/to/custom/data
404
+ ```
405
+
406
+ Default: `.relay/` in the project root.
407
+
408
+ ---
409
+
410
+ ## Webhook Deployment
411
+
412
+ For production deployments, you can run Relay in webhook mode instead of long-polling.
413
+
414
+ ### Setup
415
+
416
+ ```env
417
+ BOT_MODE=webhook
418
+ WEBHOOK_URL=https://your-server.com/bot
419
+ WEBHOOK_PORT=3000
420
+ WEBHOOK_SECRET=your-random-secret
421
+ ```
422
+
423
+ ### Requirements
424
+
425
+ - A public HTTPS URL that Telegram can reach
426
+ - The port (default 3000) must be accessible
427
+
428
+ ### How it works
429
+
430
+ 1. Relay starts an HTTP server on the specified port
431
+ 2. It registers the webhook URL with Telegram
432
+ 3. Telegram pushes updates directly to your server
433
+ 4. On shutdown, the webhook is automatically cleaned up
434
+
435
+ ### Switching back to polling
436
+
437
+ Set `BOT_MODE=polling` (or remove the variable). The bot will clear any stale webhook before starting long-polling.
438
+
439
+ ### Benefits over polling
440
+
441
+ - Lower latency (push vs pull)
442
+ - Reduced resource usage (no continuous polling loop)
443
+ - Better for containerized/serverless deployments
@@ -0,0 +1,102 @@
1
+ # Getting Started
2
+
3
+ This guide walks you through setting up Relay from scratch.
4
+
5
+ ## Prerequisites
6
+
7
+ - **[Node.js](https://nodejs.org/)** >= 18 (or **[Bun](https://bun.sh/)**)
8
+ - A **Telegram bot token** from [@BotFather](https://t.me/BotFather)
9
+ - Your **Telegram user ID** (get it from [@userinfobot](https://t.me/userinfobot))
10
+ - Credentials for at least one coding agent provider (see [Providers](providers.md))
11
+
12
+ ## Installation
13
+
14
+ ### From npm (recommended)
15
+
16
+ ```bash
17
+ npm install -g relay
18
+ ```
19
+
20
+ ### From source
21
+
22
+ ```bash
23
+ git clone https://github.com/Harsh-2002/relay.git
24
+ cd relay
25
+ npm install
26
+ npm run build
27
+ ```
28
+
29
+ ## Configuration
30
+
31
+ Copy the example environment file and edit it:
32
+
33
+ ```bash
34
+ cp .env.example .env
35
+ ```
36
+
37
+ Open `.env` and set the required values:
38
+
39
+ ```env
40
+ # Required for all providers
41
+ BOT_TOKEN=your-telegram-bot-token
42
+ ALLOWED_USER_ID=your-telegram-user-id
43
+
44
+ # Select your provider
45
+ PROVIDER=opencode
46
+ ```
47
+
48
+ Then configure your chosen provider. See [Providers](providers.md) for detailed setup instructions.
49
+
50
+ ## Running the Bot
51
+
52
+ Start the bot:
53
+
54
+ ```bash
55
+ # If installed globally
56
+ relay
57
+
58
+ # If running from source
59
+ npm start
60
+ ```
61
+
62
+ You should see output like:
63
+
64
+ ```
65
+ Initializing opencode provider...
66
+ opencode provider ready.
67
+ Starting Telegram bot (long polling)...
68
+ Bot @YourBotName is running!
69
+ ```
70
+
71
+ ## First Steps
72
+
73
+ 1. Open your bot in Telegram
74
+ 2. Send `/start` to verify the connection
75
+ 3. Send any text message to chat with the AI
76
+ 4. Use `/help` to see all available commands
77
+ 5. Use `/health` to check the server status
78
+
79
+ ## Project Structure
80
+
81
+ ```
82
+ relay/
83
+ .env.example -- Template for environment variables
84
+ package.json -- Dependencies and scripts
85
+ src/
86
+ index.ts -- Entry point
87
+ bot.ts -- Bot setup and middleware
88
+ auth.ts -- User authentication
89
+ session.ts -- Session state management
90
+ providers/ -- Provider implementations
91
+ commands/ -- Telegram command handlers
92
+ utils/ -- Shared utilities
93
+ docs/ -- This documentation
94
+ ```
95
+
96
+ ## Next Steps
97
+
98
+ - [Configuration Reference](configuration.md) -- All environment variables
99
+ - [Provider Setup](providers.md) -- Detailed provider configuration
100
+ - [Commands](commands.md) -- Full command reference
101
+ - [Features](features.md) -- File attachments, streaming, MCP, voice
102
+ - [Troubleshooting](troubleshooting.md) -- Common issues and fixes