izuemon commited on
Commit
0018802
·
verified ·
1 Parent(s): f6f59b1

Update turbowarp-server/gpt.py

Browse files
Files changed (1) hide show
  1. turbowarp-server/gpt.py +219 -90
turbowarp-server/gpt.py CHANGED
@@ -1,6 +1,7 @@
1
  import scratchcommunication
2
  import time
3
  import requests
 
4
 
5
  PROJECT_ID = "1290918780"
6
 
@@ -22,190 +23,318 @@ slots = [f"n{i}" for i in range(1, 10)]
22
  # ---------------------
23
 
24
  chars = []
 
25
  with open("turbowarp-server/n-chars.txt", encoding="utf8") as f:
26
  for line in f:
27
  chars.append(line.strip())
28
 
 
 
 
 
 
 
 
29
  def encode(text):
 
30
  out = ""
 
31
  for c in text:
32
- if c in chars:
33
- i = chars.index(c)
34
- out += f"{i:02d}"
 
 
 
 
 
 
35
  return out
36
 
 
37
  def decode(data):
 
38
  text = ""
39
- for i in range(0, len(data), 2):
40
- num = int(data[i:i+2])
41
- if num == 99:
42
- text += "\n"
43
- else:
44
- text += chars[num]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  return text
46
 
 
47
  # ---------------------
48
- # TwCloudConnection の正しいラッパー
49
  # ---------------------
50
 
51
  def get_var(name):
52
- """
53
- TwCloudConnection の get_variable はキーワード引数で使う必要があるので
54
- ここでラップする(戻り値はそのまま)。
55
- """
56
  try:
57
- # name_literal を必要に応じて True に切り替えてください
58
- return tw.get_variable(name=name, name_literal=False)
 
59
  except Exception:
60
- # 例外は None を返す(呼び出し側でチェック)
 
61
  return None
62
 
 
63
  def set_var(name, value):
 
64
  try:
65
- return tw.set_variable(name=name, value=value, name_literal=False)
 
 
66
  except Exception:
67
- return None
 
 
 
68
 
69
  # ---------------------
70
  # n0管理
71
  # ---------------------
72
 
73
  def get_used():
 
74
  v = get_var("n0")
 
75
  if not v:
76
  return []
 
77
  return list(v)
78
 
 
79
  def add_used(i):
 
80
  u = get_used()
 
81
  if str(i) not in u:
82
  u.append(str(i))
 
83
  set_var("n0", "".join(u))
84
 
 
85
  def remove_used(i):
 
86
  u = get_used()
 
87
  if str(i) in u:
88
  u.remove(str(i))
 
89
  set_var("n0", "".join(u))
90
 
 
91
  # ---------------------
92
  # API
93
  # ---------------------
94
 
95
  def ask_gpt(history):
96
- messages = [SYSTEM_PROMPT] + history
97
- r = requests.post(
98
- "https://izuemon-phi-3.hf.space/v1/chat/completions",
99
- json={
100
- "model": "gpt-3.5-turbo",
101
- "messages": messages
102
- },
103
- timeout=30
104
- )
105
- r.raise_for_status()
106
- data = r.json()
107
- return data["choices"][0]["message"]["content"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
 
109
  # ---------------------
110
  # 送信
111
  # ---------------------
112
 
113
  def send(slot, text):
 
 
 
114
  encoded = encode(text)
115
 
116
- # TurboWarp 環境なら問題ないとのことなのでそのまま
 
 
 
117
  size = 99996
118
 
119
  packets = [encoded[i:i+size] for i in range(0, len(encoded), size)]
 
120
  total = len(packets)
121
 
122
- for p in packets:
 
 
 
123
  packet = f"1{total}0{p}"
 
 
 
124
  start = time.time()
125
- set_var(slot, packet)
 
 
 
126
 
127
  while True:
 
128
  v = get_var(slot)
129
- # 値が存在して、長さが期待を満たすか、安全に確認
130
  if v and len(v) > 2 and v[2] == "1":
 
131
  break
 
132
  if time.time() - start > 10:
133
- # タイムアウト
134
  return
 
135
  time.sleep(0.1)
136
 
 
137
  # ---------------------
138
  # メインループ
139
  # ---------------------
140
 
141
  buffers = {}
142
 
 
 
143
  while True:
144
- for i, slot in enumerate(slots, 1):
145
- v = get_var(slot)
146
-
147
- if not v:
148
- continue
149
-
150
- if len(v) < 3:
151
- continue
152
-
153
- # 追加: 送信パケットは無視
154
- if v[0] != "0":
155
- continue
156
-
157
- unread = v[2] == "0"
158
- if not unread:
159
- continue
160
-
161
- add_used(i)
162
-
163
- # v のフォーマットは "フラグ(1桁) + total(1桁) + '0' + データ..." の前提
164
- try:
165
- total = int(v[1])
166
- except Exception:
167
- # 不正データならスキップして使用解除
168
- remove_used(i)
169
- continue
170
 
171
- data = v[3:]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
 
173
- # 既読フラグを立てる(インデックス 2 を "1" にする)
174
- # 文字列操作で安全にセット
175
- if len(v) >= 3:
176
  newv = v[:2] + "1" + v[3:]
177
  set_var(slot, newv)
178
 
179
- if slot not in buffers:
180
- buffers[slot] = []
181
 
182
- buffers[slot].append(data)
183
 
184
- if len(buffers[slot]) < total:
185
- continue
186
 
187
- joined = "".join(buffers[slot])
188
- decoded = decode(joined)
189
 
190
- history = []
191
- parts = decoded.split("\n")
192
 
193
- for j in range(0, len(parts), 2):
194
- # parts[j] がユーザーメッセージ、parts[j+1] が(将来の拡張用など)
195
- if parts[j].strip() == "":
196
- continue
197
- history.append({
198
- "role": "user",
199
- "content": parts[j]
200
- })
201
 
202
- try:
203
- reply = ask_gpt(history)
204
- except Exception:
205
- reply = "エラーが発生しました。"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
 
207
- send(slot, reply)
208
- buffers[slot] = []
209
- remove_used(i)
 
 
 
 
 
 
 
 
 
 
210
 
211
  time.sleep(0.2)
 
1
  import scratchcommunication
2
  import time
3
  import requests
4
+ import traceback
5
 
6
  PROJECT_ID = "1290918780"
7
 
 
23
  # ---------------------
24
 
25
  chars = []
26
+
27
  with open("turbowarp-server/n-chars.txt", encoding="utf8") as f:
28
  for line in f:
29
  chars.append(line.strip())
30
 
31
+ # 高速化用マップ
32
+ char_map = {c: i for i, c in enumerate(chars)}
33
+
34
+ # ---------------------
35
+ # encode / decode
36
+ # ---------------------
37
+
38
  def encode(text):
39
+
40
  out = ""
41
+
42
  for c in text:
43
+ try:
44
+ if c in char_map:
45
+ out += f"{char_map[c]:02d}"
46
+ else:
47
+ print("encode skip unknown char:", c)
48
+ except Exception:
49
+ print("ENCODE ERROR")
50
+ print(traceback.format_exc())
51
+
52
  return out
53
 
54
+
55
  def decode(data):
56
+
57
  text = ""
58
+
59
+ try:
60
+
61
+ for i in range(0, len(data), 2):
62
+
63
+ part = data[i:i+2]
64
+
65
+ if len(part) < 2:
66
+ print("decode broken pair:", part)
67
+ continue
68
+
69
+ num = int(part)
70
+
71
+ if num == 99:
72
+ text += "\n"
73
+
74
+ elif num < len(chars):
75
+ text += chars[num]
76
+
77
+ else:
78
+ print("decode invalid index:", num)
79
+
80
+ except Exception:
81
+ print("DECODE ERROR")
82
+ print(traceback.format_exc())
83
+
84
  return text
85
 
86
+
87
  # ---------------------
88
+ # TwCloudConnection
89
  # ---------------------
90
 
91
  def get_var(name):
92
+
 
 
 
93
  try:
94
+ v = tw.get_variable(name=name, name_literal=False)
95
+ return v
96
+
97
  except Exception:
98
+ print("get_var error:", name)
99
+ print(traceback.format_exc())
100
  return None
101
 
102
+
103
  def set_var(name, value):
104
+
105
  try:
106
+ tw.set_variable(name=name, value=value, name_literal=False)
107
+ return True
108
+
109
  except Exception:
110
+ print("set_var error:", name)
111
+ print(traceback.format_exc())
112
+ return False
113
+
114
 
115
  # ---------------------
116
  # n0管理
117
  # ---------------------
118
 
119
  def get_used():
120
+
121
  v = get_var("n0")
122
+
123
  if not v:
124
  return []
125
+
126
  return list(v)
127
 
128
+
129
  def add_used(i):
130
+
131
  u = get_used()
132
+
133
  if str(i) not in u:
134
  u.append(str(i))
135
+
136
  set_var("n0", "".join(u))
137
 
138
+
139
  def remove_used(i):
140
+
141
  u = get_used()
142
+
143
  if str(i) in u:
144
  u.remove(str(i))
145
+
146
  set_var("n0", "".join(u))
147
 
148
+
149
  # ---------------------
150
  # API
151
  # ---------------------
152
 
153
  def ask_gpt(history):
154
+
155
+ try:
156
+
157
+ messages = [SYSTEM_PROMPT] + history
158
+
159
+ print("API request start")
160
+
161
+ r = requests.post(
162
+ "https://izuemon-phi-3.hf.space/v1/chat/completions",
163
+ json={
164
+ "model": "gpt-3.5-turbo",
165
+ "messages": messages
166
+ },
167
+ timeout=30
168
+ )
169
+
170
+ print("API status:", r.status_code)
171
+
172
+ r.raise_for_status()
173
+
174
+ data = r.json()
175
+
176
+ reply = data["choices"][0]["message"]["content"]
177
+
178
+ print("API reply length:", len(reply))
179
+
180
+ return reply
181
+
182
+ except requests.exceptions.Timeout:
183
+ print("API timeout")
184
+ return "APIタイムアウト"
185
+
186
+ except requests.exceptions.RequestException:
187
+ print("API request error")
188
+ print(traceback.format_exc())
189
+ return "API通信エラー"
190
+
191
+ except Exception:
192
+ print("API unknown error")
193
+ print(traceback.format_exc())
194
+ return "AIエラー"
195
+
196
 
197
  # ---------------------
198
  # 送信
199
  # ---------------------
200
 
201
  def send(slot, text):
202
+
203
+ print("send to", slot)
204
+
205
  encoded = encode(text)
206
 
207
+ if not encoded:
208
+ print("encoded text empty")
209
+ return
210
+
211
  size = 99996
212
 
213
  packets = [encoded[i:i+size] for i in range(0, len(encoded), size)]
214
+
215
  total = len(packets)
216
 
217
+ print("packet count:", total)
218
+
219
+ for index, p in enumerate(packets):
220
+
221
  packet = f"1{total}0{p}"
222
+
223
+ print("send packet", index+1, "/", total)
224
+
225
  start = time.time()
226
+
227
+ if not set_var(slot, packet):
228
+ print("packet send failed")
229
+ return
230
 
231
  while True:
232
+
233
  v = get_var(slot)
234
+
235
  if v and len(v) > 2 and v[2] == "1":
236
+ print("packet confirmed")
237
  break
238
+
239
  if time.time() - start > 10:
240
+ print("packet timeout")
241
  return
242
+
243
  time.sleep(0.1)
244
 
245
+
246
  # ---------------------
247
  # メインループ
248
  # ---------------------
249
 
250
  buffers = {}
251
 
252
+ print("SERVER STARTED")
253
+
254
  while True:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
 
256
+ try:
257
+
258
+ for i, slot in enumerate(slots, 1):
259
+
260
+ v = get_var(slot)
261
+
262
+ if not v:
263
+ continue
264
+
265
+ if len(v) < 3:
266
+ print("invalid packet:", v)
267
+ continue
268
+
269
+ if v[0] != "0":
270
+ continue
271
+
272
+ unread = v[2] == "0"
273
+
274
+ if not unread:
275
+ continue
276
+
277
+ print("new message slot", slot)
278
+
279
+ add_used(i)
280
+
281
+ try:
282
+ total = int(v[1])
283
+ except Exception:
284
+ print("invalid total packet count")
285
+ remove_used(i)
286
+ continue
287
+
288
+ data = v[3:]
289
 
 
 
 
290
  newv = v[:2] + "1" + v[3:]
291
  set_var(slot, newv)
292
 
293
+ if slot not in buffers:
294
+ buffers[slot] = []
295
 
296
+ buffers[slot].append(data)
297
 
298
+ if len(buffers[slot]) < total:
299
+ continue
300
 
301
+ joined = "".join(buffers[slot])
 
302
 
303
+ print("joined length:", len(joined))
 
304
 
305
+ decoded = decode(joined)
 
 
 
 
 
 
 
306
 
307
+ print("decoded message:", decoded)
308
+
309
+ history = []
310
+
311
+ parts = decoded.split("\n")
312
+
313
+ for j in range(0, len(parts), 2):
314
+
315
+ if parts[j].strip() == "":
316
+ continue
317
+
318
+ history.append({
319
+ "role": "user",
320
+ "content": parts[j]
321
+ })
322
+
323
+ try:
324
+ reply = ask_gpt(history)
325
 
326
+ except Exception:
327
+ print("AI call failed")
328
+ reply = "AIエラー"
329
+
330
+ send(slot, reply)
331
+
332
+ buffers[slot] = []
333
+
334
+ remove_used(i)
335
+
336
+ except Exception:
337
+ print("MAIN LOOP ERROR")
338
+ print(traceback.format_exc())
339
 
340
  time.sleep(0.2)