linkgravity 1.4.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
package/src/main_telegram.py
CHANGED
|
@@ -14,7 +14,7 @@ from config import TELEGRAM_TOKEN, allowed, bot_settings, logger, save_bot_setti
|
|
|
14
14
|
from core.atomic_io import atomic_write_json, safe_load_json
|
|
15
15
|
from handlers.message_router import handle_message
|
|
16
16
|
from messengers.registry import register_adapter
|
|
17
|
-
from messengers.telegram_adapter import TelegramAdapter, markdown_to_telegram_html
|
|
17
|
+
from messengers.telegram_adapter import TelegramAdapter, markdown_to_telegram_html, safe_query_edit
|
|
18
18
|
from utils.utils import get_default_cwd
|
|
19
19
|
|
|
20
20
|
|
|
@@ -91,21 +91,45 @@ async def cmd_model(update: Update, context) -> None:
|
|
|
91
91
|
await update.message.reply_text("⚠️ No active session here. Start one with /new first.")
|
|
92
92
|
return
|
|
93
93
|
|
|
94
|
+
from cogs.general_cog import load_cached_models
|
|
95
|
+
|
|
96
|
+
cached_models = load_cached_models()
|
|
97
|
+
current_model = session.get("model") or bot_settings.get("default_model")
|
|
98
|
+
|
|
99
|
+
def _apply_model(final_model: str) -> str:
|
|
100
|
+
session_manager.update_session(str(chat_id), "model", final_model)
|
|
101
|
+
bot_settings["default_model"] = final_model
|
|
102
|
+
save_bot_settings(bot_settings)
|
|
103
|
+
return final_model
|
|
104
|
+
|
|
94
105
|
if not context.args:
|
|
95
|
-
|
|
106
|
+
prompt_id = uuid.uuid4().hex[:12]
|
|
107
|
+
keyboard = []
|
|
108
|
+
for m in cached_models:
|
|
109
|
+
key = f"{prompt_id}:{m}"
|
|
110
|
+
label = ("✅ " if m == current_model else "") + m
|
|
111
|
+
|
|
112
|
+
async def pick(query, m=m):
|
|
113
|
+
final_model = _apply_model(m)
|
|
114
|
+
await query.answer()
|
|
115
|
+
await safe_query_edit(
|
|
116
|
+
query,
|
|
117
|
+
text=markdown_to_telegram_html(f"🤖 Model changed: **{final_model}**"),
|
|
118
|
+
parse_mode="HTML",
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
adapter.register_callback(key, pick)
|
|
122
|
+
keyboard.append([InlineKeyboardButton(label, callback_data=key)])
|
|
123
|
+
|
|
124
|
+
await update.message.reply_text(
|
|
125
|
+
"Pick a model (or send /model <name> to type one):", reply_markup=InlineKeyboardMarkup(keyboard)
|
|
126
|
+
)
|
|
96
127
|
return
|
|
97
128
|
|
|
98
129
|
requested = " ".join(context.args)
|
|
99
|
-
from cogs.general_cog import load_cached_models
|
|
100
|
-
|
|
101
|
-
cached_models = load_cached_models()
|
|
102
130
|
exact = next((m for m in cached_models if m.lower() == requested.lower()), None)
|
|
103
131
|
partial = next((m for m in cached_models if requested.lower() in m.lower()), None)
|
|
104
|
-
final_model = exact or partial or requested
|
|
105
|
-
|
|
106
|
-
session_manager.update_session(str(chat_id), "model", final_model)
|
|
107
|
-
bot_settings["default_model"] = final_model
|
|
108
|
-
save_bot_settings(bot_settings)
|
|
132
|
+
final_model = _apply_model(exact or partial or requested)
|
|
109
133
|
|
|
110
134
|
await adapter.send_message(
|
|
111
135
|
chat_id, f"🤖 Model changed: **{final_model}**\n💾 Also set as the default for new sessions."
|
|
@@ -114,27 +138,47 @@ async def cmd_model(update: Update, context) -> None:
|
|
|
114
138
|
|
|
115
139
|
async def cmd_credit(update: Update, context) -> None:
|
|
116
140
|
user = update.effective_user
|
|
141
|
+
adapter: TelegramAdapter = context.bot_data["adapter"]
|
|
142
|
+
|
|
117
143
|
if not allowed(user.id, "telegram"):
|
|
118
144
|
await update.message.reply_text("❌ Denied")
|
|
119
145
|
return
|
|
120
146
|
|
|
121
|
-
if not context.args or context.args[0].lower() not in ("on", "off"):
|
|
122
|
-
await update.message.reply_text("Usage: /credit <on|off>")
|
|
123
|
-
return
|
|
124
|
-
|
|
125
|
-
use_credits = context.args[0].lower() == "on"
|
|
126
147
|
settings_path = Path(os.getenv("HOME", "/root")) / ".gemini/antigravity-cli/settings.json"
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
148
|
+
current = bool(safe_load_json(settings_path, {}, logger=logger).get("useG1Credits", False))
|
|
149
|
+
|
|
150
|
+
async def set_credit(use_credits: bool, query) -> None:
|
|
151
|
+
try:
|
|
152
|
+
data = safe_load_json(settings_path, {}, logger=logger)
|
|
153
|
+
data["useG1Credits"] = use_credits
|
|
154
|
+
atomic_write_json(settings_path, data)
|
|
155
|
+
except Exception as e:
|
|
156
|
+
await query.answer()
|
|
157
|
+
await safe_query_edit(query, text=f"⚠️ Failed to update settings: {e}")
|
|
158
|
+
return
|
|
131
159
|
|
|
132
160
|
status_text = "🟢 **ON** (Using AI Credits)" if use_credits else "🔴 **OFF** (Using default/free model)"
|
|
133
|
-
await
|
|
134
|
-
|
|
161
|
+
await query.answer()
|
|
162
|
+
await safe_query_edit(
|
|
163
|
+
query,
|
|
164
|
+
text=markdown_to_telegram_html(f"✅ AI Credit setting updated: {status_text}"),
|
|
165
|
+
parse_mode="HTML",
|
|
135
166
|
)
|
|
136
|
-
|
|
137
|
-
|
|
167
|
+
|
|
168
|
+
prompt_id = uuid.uuid4().hex[:12]
|
|
169
|
+
on_key, off_key = f"{prompt_id}:on", f"{prompt_id}:off"
|
|
170
|
+
adapter.register_callback(on_key, lambda query: set_credit(True, query))
|
|
171
|
+
adapter.register_callback(off_key, lambda query: set_credit(False, query))
|
|
172
|
+
|
|
173
|
+
keyboard = InlineKeyboardMarkup(
|
|
174
|
+
[
|
|
175
|
+
[
|
|
176
|
+
InlineKeyboardButton(("✅ " if current else "") + "🟢 ON", callback_data=on_key),
|
|
177
|
+
InlineKeyboardButton(("✅ " if not current else "") + "🔴 OFF", callback_data=off_key),
|
|
178
|
+
]
|
|
179
|
+
]
|
|
180
|
+
)
|
|
181
|
+
await update.message.reply_text("AI Credits:", reply_markup=keyboard)
|
|
138
182
|
|
|
139
183
|
|
|
140
184
|
async def on_message(update: Update, context) -> None:
|
|
@@ -192,6 +236,8 @@ async def run_telegram(stop_event: asyncio.Event) -> None:
|
|
|
192
236
|
app = build_application()
|
|
193
237
|
logger.info("✅ Telegram bot starting (polling mode)...")
|
|
194
238
|
await app.initialize()
|
|
239
|
+
if app.post_init: # not auto-called outside run_polling()/run_webhook()
|
|
240
|
+
await app.post_init(app)
|
|
195
241
|
await app.start()
|
|
196
242
|
await app.updater.start_polling(allowed_updates=Update.ALL_TYPES)
|
|
197
243
|
try:
|
|
@@ -200,3 +246,5 @@ async def run_telegram(stop_event: asyncio.Event) -> None:
|
|
|
200
246
|
await app.updater.stop()
|
|
201
247
|
await app.stop()
|
|
202
248
|
await app.shutdown()
|
|
249
|
+
if app.post_shutdown: # same gotcha as post_init: not auto-called here
|
|
250
|
+
await app.post_shutdown(app)
|
|
@@ -42,7 +42,7 @@ def markdown_to_telegram_html(text: str) -> str:
|
|
|
42
42
|
return "".join(out)
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
async def
|
|
45
|
+
async def safe_query_edit(query, **kwargs) -> None:
|
|
46
46
|
try:
|
|
47
47
|
await query.edit_message_text(**kwargs)
|
|
48
48
|
except TelegramError as e:
|
|
@@ -258,7 +258,7 @@ class TelegramAdapter(MessengerAdapter):
|
|
|
258
258
|
new_text = "❌ <b>Rejected</b>"
|
|
259
259
|
handle.text = new_text
|
|
260
260
|
await query.answer()
|
|
261
|
-
await
|
|
261
|
+
await safe_query_edit(query, text=new_text, parse_mode="HTML")
|
|
262
262
|
|
|
263
263
|
allow_key = f"{prompt_id}:allow"
|
|
264
264
|
self._callbacks[allow_key] = lambda query: resolve("allow", None, query)
|
|
@@ -303,11 +303,11 @@ class TelegramAdapter(MessengerAdapter):
|
|
|
303
303
|
new_text = f"✅ <b>{note}: {html.escape(chosen_text)}</b>"
|
|
304
304
|
handle.text = new_text
|
|
305
305
|
await query.answer()
|
|
306
|
-
await
|
|
306
|
+
await safe_query_edit(query, text=new_text, parse_mode="HTML")
|
|
307
307
|
|
|
308
308
|
async def write_in(query):
|
|
309
309
|
await query.answer()
|
|
310
|
-
await
|
|
310
|
+
await safe_query_edit(
|
|
311
311
|
query,
|
|
312
312
|
text=f"❓ <b>{html.escape(question)}</b>\n\n💬 Reply with your answer as a message.",
|
|
313
313
|
parse_mode="HTML",
|