telegram-opencode-bridge-bot 0.1.3__tar.gz → 0.1.5__tar.gz
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.
- {telegram_opencode_bridge_bot-0.1.3/telegram_opencode_bridge_bot.egg-info → telegram_opencode_bridge_bot-0.1.5}/PKG-INFO +9 -10
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/README.md +8 -9
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/bot.py +66 -19
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/handlers/commands.py +578 -319
- telegram_opencode_bridge_bot-0.1.5/handlers/messages.py +818 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/opencode/client.py +48 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/pyproject.toml +1 -1
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5/telegram_opencode_bridge_bot.egg-info}/PKG-INFO +9 -10
- telegram_opencode_bridge_bot-0.1.3/handlers/messages.py +0 -482
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/.env.example +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/MANIFEST.in +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/config.py +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/handlers/__init__.py +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/list_session_models.py +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/opencode/__init__.py +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/opencode/server.py +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/requirements.txt +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/sessions/__init__.py +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/sessions/manager.py +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/setup.cfg +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/telegram_opencode_bridge_bot.egg-info/SOURCES.txt +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/telegram_opencode_bridge_bot.egg-info/dependency_links.txt +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/telegram_opencode_bridge_bot.egg-info/entry_points.txt +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/telegram_opencode_bridge_bot.egg-info/requires.txt +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/telegram_opencode_bridge_bot.egg-info/top_level.txt +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/utils/__init__.py +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/utils/formatting.py +0 -0
- {telegram_opencode_bridge_bot-0.1.3 → telegram_opencode_bridge_bot-0.1.5}/utils/security.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: telegram-opencode-bridge-bot
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: A Telegram bot that bridges messages directly to OpenCode — an AI coding agent running on your machine
|
|
5
5
|
Author-email: MaheshNagabhairava <maheshnagabhirava12345@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -30,6 +30,7 @@ A lightweight Python bot that bridges your Telegram messages directly to [OpenCo
|
|
|
30
30
|
- **Auto message splitting** — handles responses longer than Telegram's 4096 char limit
|
|
31
31
|
- **Security** — whitelist-based access control + rate limiting
|
|
32
32
|
- **Workspace Switching** — Switching from one workspace to another
|
|
33
|
+
- **Uploading from Mobile to WorkSpace** - U can upload the documents/images from your mobile to the opencode agent workspace
|
|
33
34
|
|
|
34
35
|
## 📋 Prerequisites
|
|
35
36
|
|
|
@@ -45,7 +46,7 @@ A lightweight Python bot that bridges your Telegram messages directly to [OpenCo
|
|
|
45
46
|
|
|
46
47
|
### Quick Installation:
|
|
47
48
|
```bash
|
|
48
|
-
pip install telegram-opencode-bridge-bot==0.1.
|
|
49
|
+
pip install telegram-opencode-bridge-bot==0.1.5
|
|
49
50
|
telegram-opencode-bot
|
|
50
51
|
telegram-opencode-bot --env (use --env flag if u want to re-configure later anytime)
|
|
51
52
|
```
|
|
@@ -76,17 +77,15 @@ Open Telegram, find your bot, and start asking! 🎉
|
|
|
76
77
|
| `/start` | Welcome message & connection check |
|
|
77
78
|
| `/help` | Show all commands |
|
|
78
79
|
| `/new` | Start a fresh conversation |
|
|
79
|
-
| `/sessions` | List your recent sessions |
|
|
80
|
-
| `/
|
|
81
|
-
| `/
|
|
82
|
-
| `/
|
|
83
|
-
| `/share` | Share current session (public URL) |
|
|
80
|
+
| `/sessions` | List your recent sessions/conversations and to select a session/conversation |
|
|
81
|
+
| `/plan` | plan mode |
|
|
82
|
+
| `/build` | build mode |
|
|
83
|
+
| `/share` | Share current session/conversation (public URL) |
|
|
84
84
|
| `/status` | Check connection & session details |
|
|
85
85
|
| `/id` | Show your Telegram user ID |
|
|
86
86
|
| `/stop` | Abort active model processing |
|
|
87
|
-
| `/models` | List all available models |
|
|
88
|
-
| `/project` | To view the current workspace, sub folder workspaces and to change the workspace
|
|
89
|
-
| `/project depth <1to5>` | Depth level recursive check for subfolders (ex: if u give depth 2, only 2 sub folders it will show from root) |
|
|
87
|
+
| `/models` | List all available providers, models and to select the model |
|
|
88
|
+
| `/project` | To view the current workspace, sub folder workspaces and to change the workspace |
|
|
90
89
|
| `/enable` | To enable the streaming |
|
|
91
90
|
| `/disable` | To disable the streaming |
|
|
92
91
|
|
|
@@ -13,6 +13,7 @@ A lightweight Python bot that bridges your Telegram messages directly to [OpenCo
|
|
|
13
13
|
- **Auto message splitting** — handles responses longer than Telegram's 4096 char limit
|
|
14
14
|
- **Security** — whitelist-based access control + rate limiting
|
|
15
15
|
- **Workspace Switching** — Switching from one workspace to another
|
|
16
|
+
- **Uploading from Mobile to WorkSpace** - U can upload the documents/images from your mobile to the opencode agent workspace
|
|
16
17
|
|
|
17
18
|
## 📋 Prerequisites
|
|
18
19
|
|
|
@@ -28,7 +29,7 @@ A lightweight Python bot that bridges your Telegram messages directly to [OpenCo
|
|
|
28
29
|
|
|
29
30
|
### Quick Installation:
|
|
30
31
|
```bash
|
|
31
|
-
pip install telegram-opencode-bridge-bot==0.1.
|
|
32
|
+
pip install telegram-opencode-bridge-bot==0.1.5
|
|
32
33
|
telegram-opencode-bot
|
|
33
34
|
telegram-opencode-bot --env (use --env flag if u want to re-configure later anytime)
|
|
34
35
|
```
|
|
@@ -59,17 +60,15 @@ Open Telegram, find your bot, and start asking! 🎉
|
|
|
59
60
|
| `/start` | Welcome message & connection check |
|
|
60
61
|
| `/help` | Show all commands |
|
|
61
62
|
| `/new` | Start a fresh conversation |
|
|
62
|
-
| `/sessions` | List your recent sessions |
|
|
63
|
-
| `/
|
|
64
|
-
| `/
|
|
65
|
-
| `/
|
|
66
|
-
| `/share` | Share current session (public URL) |
|
|
63
|
+
| `/sessions` | List your recent sessions/conversations and to select a session/conversation |
|
|
64
|
+
| `/plan` | plan mode |
|
|
65
|
+
| `/build` | build mode |
|
|
66
|
+
| `/share` | Share current session/conversation (public URL) |
|
|
67
67
|
| `/status` | Check connection & session details |
|
|
68
68
|
| `/id` | Show your Telegram user ID |
|
|
69
69
|
| `/stop` | Abort active model processing |
|
|
70
|
-
| `/models` | List all available models |
|
|
71
|
-
| `/project` | To view the current workspace, sub folder workspaces and to change the workspace
|
|
72
|
-
| `/project depth <1to5>` | Depth level recursive check for subfolders (ex: if u give depth 2, only 2 sub folders it will show from root) |
|
|
70
|
+
| `/models` | List all available providers, models and to select the model |
|
|
71
|
+
| `/project` | To view the current workspace, sub folder workspaces and to change the workspace |
|
|
73
72
|
| `/enable` | To enable the streaming |
|
|
74
73
|
| `/disable` | To disable the streaming |
|
|
75
74
|
|
|
@@ -24,9 +24,12 @@ from telegram.ext import (
|
|
|
24
24
|
ApplicationBuilder,
|
|
25
25
|
CommandHandler,
|
|
26
26
|
MessageHandler,
|
|
27
|
+
CallbackQueryHandler,
|
|
27
28
|
filters,
|
|
28
29
|
ContextTypes,
|
|
29
30
|
)
|
|
31
|
+
from telegram.request import HTTPXRequest
|
|
32
|
+
from telegram.error import TimedOut, NetworkError
|
|
30
33
|
from utils.formatting import format_error
|
|
31
34
|
|
|
32
35
|
from config import config
|
|
@@ -38,9 +41,8 @@ from handlers.commands import (
|
|
|
38
41
|
help_command,
|
|
39
42
|
new_command,
|
|
40
43
|
sessions_command,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
mode_command,
|
|
44
|
+
plan_command,
|
|
45
|
+
build_command,
|
|
44
46
|
share_command,
|
|
45
47
|
status_command,
|
|
46
48
|
id_command,
|
|
@@ -50,8 +52,9 @@ from handlers.commands import (
|
|
|
50
52
|
enable_command,
|
|
51
53
|
disable_command,
|
|
52
54
|
set_bot_commands,
|
|
55
|
+
callback_handler,
|
|
53
56
|
)
|
|
54
|
-
from handlers.messages import handle_message
|
|
57
|
+
from handlers.messages import handle_message, handle_document
|
|
55
58
|
|
|
56
59
|
# ── Logging Setup ──────────────────────────────────────────
|
|
57
60
|
logging.basicConfig(
|
|
@@ -62,6 +65,25 @@ logging.basicConfig(
|
|
|
62
65
|
logger = logging.getLogger("opencode-telegram-bot")
|
|
63
66
|
|
|
64
67
|
|
|
68
|
+
class RetryingHTTPXRequest(HTTPXRequest):
|
|
69
|
+
"""Custom HTTPXRequest that automatically retries failed requests on connection timeouts/errors."""
|
|
70
|
+
async def do_request(self, *args, **kwargs) -> tuple[int, bytes]:
|
|
71
|
+
max_retries = 3
|
|
72
|
+
for attempt in range(max_retries):
|
|
73
|
+
try:
|
|
74
|
+
return await super().do_request(*args, **kwargs)
|
|
75
|
+
except (TimedOut, NetworkError) as e:
|
|
76
|
+
# Do not retry on Pool timeout errors
|
|
77
|
+
if "Pool timeout" in str(e) or attempt == max_retries - 1:
|
|
78
|
+
raise
|
|
79
|
+
|
|
80
|
+
logger.warning(
|
|
81
|
+
f"⚠️ Telegram request failed (attempt {attempt + 1}/{max_retries}): {e}. "
|
|
82
|
+
f"Retrying in {1.0 * (attempt + 1)}s..."
|
|
83
|
+
)
|
|
84
|
+
await asyncio.sleep(1.0 * (attempt + 1))
|
|
85
|
+
|
|
86
|
+
|
|
65
87
|
# ── Wrap handlers with auth decorator ──────────────────────
|
|
66
88
|
|
|
67
89
|
def build_authorized_handlers(authorizer: UserAuthorizer, rate_limiter: RateLimiter):
|
|
@@ -84,16 +106,12 @@ def build_authorized_handlers(authorizer: UserAuthorizer, rate_limiter: RateLimi
|
|
|
84
106
|
await sessions_command(update, context)
|
|
85
107
|
|
|
86
108
|
@authorized(authorizer, rate_limiter)
|
|
87
|
-
async def
|
|
88
|
-
await
|
|
109
|
+
async def _plan(update, context):
|
|
110
|
+
await plan_command(update, context)
|
|
89
111
|
|
|
90
112
|
@authorized(authorizer, rate_limiter)
|
|
91
|
-
async def
|
|
92
|
-
await
|
|
93
|
-
|
|
94
|
-
@authorized(authorizer, rate_limiter)
|
|
95
|
-
async def _mode(update, context):
|
|
96
|
-
await mode_command(update, context)
|
|
113
|
+
async def _build(update, context):
|
|
114
|
+
await build_command(update, context)
|
|
97
115
|
|
|
98
116
|
@authorized(authorizer, rate_limiter)
|
|
99
117
|
async def _share(update, context):
|
|
@@ -127,27 +145,36 @@ def build_authorized_handlers(authorizer: UserAuthorizer, rate_limiter: RateLimi
|
|
|
127
145
|
async def _disable(update, context):
|
|
128
146
|
await disable_command(update, context)
|
|
129
147
|
|
|
148
|
+
@authorized(authorizer)
|
|
149
|
+
async def _callback(update, context):
|
|
150
|
+
await callback_handler(update, context)
|
|
151
|
+
|
|
130
152
|
@authorized(authorizer, rate_limiter)
|
|
131
153
|
async def _message(update, context):
|
|
132
154
|
await handle_message(update, context)
|
|
133
155
|
|
|
156
|
+
@authorized(authorizer, rate_limiter)
|
|
157
|
+
async def _document(update, context):
|
|
158
|
+
await handle_document(update, context)
|
|
159
|
+
|
|
134
160
|
return {
|
|
135
161
|
"start": _start,
|
|
136
162
|
"help": _help,
|
|
137
163
|
"new": _new,
|
|
138
164
|
"sessions": _sessions,
|
|
139
|
-
"switch": _switch,
|
|
140
|
-
"model": _model,
|
|
141
165
|
"models": _models,
|
|
142
166
|
"stop": _stop,
|
|
143
167
|
"project": _project,
|
|
144
168
|
"enable": _enable,
|
|
145
169
|
"disable": _disable,
|
|
146
|
-
"
|
|
170
|
+
"plan": _plan,
|
|
171
|
+
"build": _build,
|
|
147
172
|
"share": _share,
|
|
148
173
|
"status": _status,
|
|
149
174
|
"id": _id,
|
|
175
|
+
"callback": _callback,
|
|
150
176
|
"message": _message,
|
|
177
|
+
"document": _document,
|
|
151
178
|
}
|
|
152
179
|
|
|
153
180
|
|
|
@@ -390,9 +417,18 @@ def main():
|
|
|
390
417
|
session_mgr = SessionManager(db_path=config.db_path)
|
|
391
418
|
|
|
392
419
|
# ── Build Telegram application ────────────────────────
|
|
420
|
+
request = RetryingHTTPXRequest(
|
|
421
|
+
connect_timeout=15.0,
|
|
422
|
+
read_timeout=20.0,
|
|
423
|
+
write_timeout=20.0,
|
|
424
|
+
pool_timeout=5.0,
|
|
425
|
+
connection_pool_size=512,
|
|
426
|
+
)
|
|
427
|
+
|
|
393
428
|
application = (
|
|
394
429
|
ApplicationBuilder()
|
|
395
430
|
.token(config.telegram_bot_token)
|
|
431
|
+
.request(request)
|
|
396
432
|
.post_init(post_init)
|
|
397
433
|
.post_shutdown(post_shutdown)
|
|
398
434
|
.build()
|
|
@@ -415,18 +451,20 @@ def main():
|
|
|
415
451
|
application.add_handler(CommandHandler("help", handlers["help"], block=False))
|
|
416
452
|
application.add_handler(CommandHandler("new", handlers["new"], block=False))
|
|
417
453
|
application.add_handler(CommandHandler("sessions", handlers["sessions"], block=False))
|
|
418
|
-
application.add_handler(CommandHandler("switch", handlers["switch"], block=False))
|
|
419
|
-
application.add_handler(CommandHandler("model", handlers["model"], block=False))
|
|
420
454
|
application.add_handler(CommandHandler("models", handlers["models"], block=False))
|
|
421
455
|
application.add_handler(CommandHandler("stop", handlers["stop"], block=False))
|
|
422
456
|
application.add_handler(CommandHandler("project", handlers["project"], block=False))
|
|
423
457
|
application.add_handler(CommandHandler("enable", handlers["enable"], block=False))
|
|
424
458
|
application.add_handler(CommandHandler("disable", handlers["disable"], block=False))
|
|
425
|
-
application.add_handler(CommandHandler("
|
|
459
|
+
application.add_handler(CommandHandler("plan", handlers["plan"], block=False))
|
|
460
|
+
application.add_handler(CommandHandler("build", handlers["build"], block=False))
|
|
426
461
|
application.add_handler(CommandHandler("share", handlers["share"], block=False))
|
|
427
462
|
application.add_handler(CommandHandler("status", handlers["status"], block=False))
|
|
428
463
|
application.add_handler(CommandHandler("id", handlers["id"], block=False))
|
|
429
464
|
|
|
465
|
+
# ── Register callback query handler ───────────────────
|
|
466
|
+
application.add_handler(CallbackQueryHandler(handlers["callback"], block=False))
|
|
467
|
+
|
|
430
468
|
# ── Register message handler (catches all text) ───────
|
|
431
469
|
application.add_handler(
|
|
432
470
|
MessageHandler(
|
|
@@ -436,11 +474,20 @@ def main():
|
|
|
436
474
|
)
|
|
437
475
|
)
|
|
438
476
|
|
|
477
|
+
# ── Register document handler (catches file uploads) ──
|
|
478
|
+
application.add_handler(
|
|
479
|
+
MessageHandler(
|
|
480
|
+
(filters.Document.ALL | filters.PHOTO) & ~filters.COMMAND,
|
|
481
|
+
handlers["document"],
|
|
482
|
+
block=False,
|
|
483
|
+
)
|
|
484
|
+
)
|
|
485
|
+
|
|
439
486
|
# ── Start polling ─────────────────────────────────────
|
|
440
487
|
logger.info("Starting bot with long polling...")
|
|
441
488
|
application.run_polling(
|
|
442
489
|
drop_pending_updates=True,
|
|
443
|
-
allowed_updates=["message"],
|
|
490
|
+
allowed_updates=["message", "callback_query"],
|
|
444
491
|
)
|
|
445
492
|
|
|
446
493
|
|