misukisu commited on
Commit
7ae5c02
·
verified ·
1 Parent(s): 9763a0b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +151 -15
app.py CHANGED
@@ -1,6 +1,8 @@
1
  import os
2
- from telegram import Update
3
- from telegram.ext import ApplicationBuilder, MessageHandler, filters, ContextTypes
 
 
4
  from transformers import pipeline
5
 
6
  pipe = pipeline(
@@ -8,28 +10,162 @@ pipe = pipeline(
8
  model="Qwen/Qwen2-0.5B-Instruct"
9
  )
10
 
11
- def build_prompt(msg):
12
- return f"<|im_start|>user\n{msg}<|im_end|>\n<|im_start|>assistant\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  async def handle(update: Update, context: ContextTypes.DEFAULT_TYPE):
 
15
  user_msg = update.message.text
16
- prompt = build_prompt(user_msg)
17
-
18
- out = pipe(
19
- prompt,
20
- max_new_tokens=80,
21
- temperature=0.6,
22
- top_p=0.9,
23
- do_sample=True
24
- )
25
 
26
- text = out[0]["generated_text"]
27
- reply = text.split("<|im_start|>assistant")[-1].strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
  await update.message.reply_text(reply)
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  app = ApplicationBuilder().token(os.environ["TELEGRAM_TOKEN"]).build()
32
 
33
  app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle))
 
34
 
35
  app.run_polling()
 
1
  import os
2
+ import json
3
+ import math
4
+ from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
5
+ from telegram.ext import ApplicationBuilder, MessageHandler, filters, ContextTypes, CallbackQueryHandler
6
  from transformers import pipeline
7
 
8
  pipe = pipeline(
 
10
  model="Qwen/Qwen2-0.5B-Instruct"
11
  )
12
 
13
+ # 🧠 muistia käyttäjille
14
+ memory = {}
15
+
16
+ # 🛠️ TOOLS
17
+
18
+ def tool_calculate(expression: str):
19
+ try:
20
+ return str(eval(expression))
21
+ except:
22
+ return "Error"
23
+
24
+ def tool_search(query: str):
25
+ return f"(fake search result for: {query})"
26
+
27
+ TOOLS = {
28
+ "calculate": tool_calculate,
29
+ "search": tool_search
30
+ }
31
+
32
+ # 🧠 PROMPT
33
+
34
+ def build_prompt(user_id, msg):
35
+ history = memory.get(user_id, [])
36
+ history_text = "\n".join(history[-5:])
37
+
38
+ return (
39
+ "<|system|>\n"
40
+ "You are an AI agent.\n"
41
+ "You can:\n"
42
+ "- Answer normally\n"
43
+ "- Use tools\n"
44
+ "- Create buttons\n\n"
45
+
46
+ "TOOLS FORMAT:\n"
47
+ '{"type":"tool","name":"calculate","input":"2+2"}\n'
48
+ '{"type":"tool","name":"search","input":"weather Helsinki"}\n\n'
49
+
50
+ "BUTTON FORMAT:\n"
51
+ '{"type":"buttons","text":"Choose:","buttons":["A","B"]}\n\n'
52
+
53
+ "RULES:\n"
54
+ "- Only output JSON when using tools or buttons\n"
55
+ "- No explanation around JSON\n"
56
+ "- Otherwise reply normally\n"
57
+ "- Use tools when useful\n"
58
+ "- Use buttons for choices\n"
59
+ "<|end|>\n"
60
+
61
+ f"{history_text}\n"
62
+
63
+ "<|user|>\n"
64
+ f"{msg}"
65
+ "<|end|>\n"
66
+ "<|assistant|>\n"
67
+ )
68
+
69
+ # 🤖 AGENT LOOP
70
+
71
+ def run_agent(user_id, msg):
72
+ prompt = build_prompt(user_id, msg)
73
+
74
+ for _ in range(3): # max 3 tool calls
75
+ out = pipe(
76
+ prompt,
77
+ max_new_tokens=120,
78
+ temperature=0.6,
79
+ top_p=0.9,
80
+ do_sample=True
81
+ )
82
+
83
+ text = out[0]["generated_text"]
84
+ reply = text.split("<|assistant|>")[-1].strip()
85
+
86
+ # yritä parse JSON
87
+ try:
88
+ data = json.loads(reply)
89
+
90
+ # 🔘 BUTTONS
91
+ if data.get("type") == "buttons":
92
+ return {"buttons": data}
93
+
94
+ # 🛠️ TOOL CALL
95
+ if data.get("type") == "tool":
96
+ name = data.get("name")
97
+ inp = data.get("input")
98
+
99
+ if name in TOOLS:
100
+ result = TOOLS[name](inp)
101
+
102
+ # lisää contextiin
103
+ prompt += f"\nTool result: {result}\nContinue.\n"
104
+ continue
105
+
106
+ except:
107
+ pass
108
+
109
+ return {"text": reply}
110
+
111
+ return {"text": "I couldn't complete that."}
112
+
113
+ # 📩 MESSAGE HANDLER
114
 
115
  async def handle(update: Update, context: ContextTypes.DEFAULT_TYPE):
116
+ user_id = update.effective_user.id
117
  user_msg = update.message.text
 
 
 
 
 
 
 
 
 
118
 
119
+ # ⌨️ typing
120
+ await update.message.chat.send_action("typing")
121
+
122
+ result = run_agent(user_id, user_msg)
123
+
124
+ # tallenna muisti
125
+ memory.setdefault(user_id, []).append(f"User: {user_msg}")
126
+
127
+ if "buttons" in result:
128
+ data = result["buttons"]
129
+
130
+ keyboard = [
131
+ [InlineKeyboardButton(b, callback_data=b)]
132
+ for b in data["buttons"]
133
+ ]
134
+
135
+ await update.message.reply_text(
136
+ data["text"],
137
+ reply_markup=InlineKeyboardMarkup(keyboard)
138
+ )
139
+
140
+ memory[user_id].append(f"Assistant: {data['text']}")
141
+ return
142
+
143
+ reply = result["text"]
144
+
145
+ memory[user_id].append(f"Assistant: {reply}")
146
 
147
  await update.message.reply_text(reply)
148
 
149
+ # 🔘 BUTTON HANDLER
150
+
151
+ async def button_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
152
+ query = update.callback_query
153
+ await query.answer()
154
+
155
+ # treat as new user input
156
+ fake_update = Update(
157
+ update.update_id,
158
+ message=query.message
159
+ )
160
+ fake_update.message.text = query.data
161
+
162
+ await handle(fake_update, context)
163
+
164
+ # 🚀 START
165
+
166
  app = ApplicationBuilder().token(os.environ["TELEGRAM_TOKEN"]).build()
167
 
168
  app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle))
169
+ app.add_handler(CallbackQueryHandler(button_handler))
170
 
171
  app.run_polling()