nekoniii3 commited on
Commit
8de66d9
1 Parent(s): 5daca38
Files changed (2) hide show
  1. app.py +7 -5
  2. bak/app2.py +515 -0
app.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import gradio as gr
2
  import time
3
  import os
@@ -363,7 +364,7 @@ def bot(state, history, file_id):
363
 
364
  history[-1][1] = res_text
365
 
366
- yield history, image_file, ant_file, err_msg
367
 
368
  print(run.status)
369
 
@@ -393,7 +394,7 @@ def bot(state, history, file_id):
393
  # コードを追加
394
  history = history + [[None, code]]
395
 
396
- yield history, image_file, ant_file, err_msg
397
 
398
  break
399
 
@@ -473,14 +474,15 @@ with gr.Blocks() as demo:
473
  # 各コンポーネント定義
474
  chatbot = gr.Chatbot(label="チャット画面")
475
  text_msg = gr.Textbox(label="テキスト")
476
- up_file = gr.File(label="ファイルアップロード", type="filepath",interactive = True)
 
 
477
  gr.Examples(label="サンプルデータ", examples=examples, inputs=[up_file])
478
  with gr.Row():
479
  btn = gr.Button(value="送信")
480
  # btn_download = gr.Button(value="画像のダウンロード") # 保留中
481
  btn_clear = gr.ClearButton(value="リセット", components=[chatbot, text_msg, up_file, state])
482
  sys_msg = gr.Textbox(label="システムメッセージ", interactive = False)
483
- result_image = gr.Image(label="出力画像", type="filepath", interactive = False)
484
  result_file = gr.File(label="出力ファイル", type="filepath",interactive = False)
485
 
486
  # ファイルID保存用
@@ -505,7 +507,7 @@ with gr.Blocks() as demo:
505
  # language = gr.Dropdown(choices=["Japanese", "English"], value = "Japanese", label="Language", interactive = True)
506
  system_prompt = gr.Textbox(value = SYS_PROMPT_DEFAULT,lines = 5, label="Custom instructions", interactive = True)
507
  # Enter不使用
508
- code_output = gr.Dropdown(label="コード出力", choices=["OFF", "ON"], value = "ON", interactive = True)
509
 
510
  # 設定タブからChatタブに戻った時の処理
511
  chat.select(set_state, [openai_key, system_prompt, code_output, state], state)
 
1
+
2
  import gradio as gr
3
  import time
4
  import os
 
364
 
365
  history[-1][1] = res_text
366
 
367
+ yield gr.Chatbot(label=run.status ,value=history), image_file, ant_file, err_msg
368
 
369
  print(run.status)
370
 
 
394
  # コードを追加
395
  history = history + [[None, code]]
396
 
397
+ yield gr.Chatbot(label=run.status ,value=history), image_file, ant_file, err_msg
398
 
399
  break
400
 
 
474
  # 各コンポーネント定義
475
  chatbot = gr.Chatbot(label="チャット画面")
476
  text_msg = gr.Textbox(label="テキスト")
477
+ with gr.Row():
478
+ up_file = gr.File(label="ファイルアップロード", type="filepath",interactive = True)
479
+ result_image = gr.Image(label="出力画像", type="filepath", interactive = False)
480
  gr.Examples(label="サンプルデータ", examples=examples, inputs=[up_file])
481
  with gr.Row():
482
  btn = gr.Button(value="送信")
483
  # btn_download = gr.Button(value="画像のダウンロード") # 保留中
484
  btn_clear = gr.ClearButton(value="リセット", components=[chatbot, text_msg, up_file, state])
485
  sys_msg = gr.Textbox(label="システムメッセージ", interactive = False)
 
486
  result_file = gr.File(label="出力ファイル", type="filepath",interactive = False)
487
 
488
  # ファイルID保存用
 
507
  # language = gr.Dropdown(choices=["Japanese", "English"], value = "Japanese", label="Language", interactive = True)
508
  system_prompt = gr.Textbox(value = SYS_PROMPT_DEFAULT,lines = 5, label="Custom instructions", interactive = True)
509
  # Enter不使用
510
+ code_output = gr.Dropdown(label="コード出力", choices=["OFF", "ON"], value = "OFF", interactive = True)
511
 
512
  # 設定タブからChatタブに戻った時の処理
513
  chat.select(set_state, [openai_key, system_prompt, code_output, state], state)
bak/app2.py ADDED
@@ -0,0 +1,515 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import time
3
+ import os
4
+ import datetime
5
+ # from zoneinfo import ZoneInfo
6
+ from openai import OpenAI
7
+
8
+ from openai.types.beta.threads.runs import (
9
+ ToolCallsStepDetails,
10
+ )
11
+
12
+ # GPT用設定
13
+ SYS_PROMPT_DEFAULT = "あなたは優秀なアシスタントです。質問をされた場合は、質問に答えるコードを作成して実行します。回答は日本語でお願いします。"
14
+ DUMMY = "********************"
15
+ file_format = {".txt", ".csv", ".pdf"}
16
+
17
+ # 各種出力フォルダ
18
+ IMG_FOLDER = "sample_data"
19
+ ANT_FOLDER = "sample_data"
20
+
21
+ # 各種メッセージ
22
+ IMG_MSG = "(画像ファイルを追加しました。送信ボタンの下に表示されています。)"
23
+ ANT_MSG = "(下部の[出力ファイル]にファイルを追加しました。)"
24
+
25
+ # 各種設定値
26
+ MAX_TRIAL = 30 # メッセージ取得最大試行数
27
+ INTER_SEC = 3 # 試行間隔(秒)
28
+
29
+ # サンプル用情報
30
+ examples = ["sample_data/東京都年別人口.csv", "sample_data/練馬区年齢別人口.csv"]
31
+ example_toid = {"東京都年別人口.csv" : "file-GOEk4X4WpU5gBJAuHCMtiJrn"
32
+ , "練馬区年齢別人口.csv" : "file-YAFPMMqG3Zl5DRx5hTLjCfFa"}
33
+
34
+ # file_id = "file-0Ly64DA2jzE9mOFYayOKJJK0"
35
+ # file_id = "file-aVnVcpEVpsy77xQ8SlTp1WoX" # ライ麦
36
+ # file_id = "file-HFCaJbf3k7j0fhBqh1Rwf2VV" # 練馬区
37
+
38
+ # コード出力用
39
+ code_mode = {'ON': True, 'OFF': False}
40
+
41
+ def set_state(openai_key, sys_prompt, code_output, state):
42
+ """ 設定タブの情報をセッションに保存する関数 """
43
+
44
+ state["openai_key"] = openai_key
45
+ state["system_prompt"] = sys_prompt
46
+ state["code_mode"] = code_mode[code_output]
47
+
48
+ return state
49
+
50
+
51
+ def init(state, text, file):
52
+ """ 入力チェックを行う関数
53
+ ※ここで例外を起こすと入力できなくなるので次の関数でエラーにする """
54
+
55
+ err_msg = ""
56
+ file_id = None
57
+
58
+ # if state["openai_key"] == "" or state["openai_key"] is None:
59
+
60
+ # # OpenAI API Key未入力
61
+ # err_msg = "OpenAI API Keyを入力してください。(設定タブ)"
62
+
63
+ if not text:
64
+
65
+ # テキスト未入力
66
+ err_msg = "テキストを入力して下さい。"
67
+
68
+ return state, text, file, file_id, err_msg
69
+
70
+ elif file:
71
+
72
+ # 入力画像のファイル形式チェック
73
+ root, ext = os.path.splitext(file)
74
+
75
+ if ext not in file_format:
76
+
77
+ # ファイル形式チェック
78
+ err_msg = "指定した形式のファイルをアップしてください。(注意事項タブに記載)"
79
+
80
+ return state, text, gr.Image(value=None,type="filepath", interactive=False), file_id, err_msg
81
+
82
+ if state["client"] is None:
83
+
84
+ # 初回起動時は初期処理をする
85
+ os.environ["OPENAI_API_KEY"] = os.environ["TEST_OPENAI_KEY"] # テスト時
86
+
87
+ # os.environ["OPENAI_API_KEY"] = state["openai_key"]
88
+
89
+ client = OpenAI()
90
+
91
+ # client作成後は消す
92
+ os.environ["OPENAI_API_KEY"] = ""
93
+
94
+ # アシスタント作成
95
+ # assistant = client.beta.assistants.create(
96
+ # name="codeinter_test",
97
+ # instructions=state["system_prompt"],
98
+ # # model="gpt-4-1106-preview",
99
+ # model="gpt-3.5-turbo-1106",
100
+ # tools=[{"type": "code_interpreter"}]
101
+ # )
102
+
103
+ # print(assistant.id)
104
+
105
+ # スレッド作成
106
+ thread = client.beta.threads.create()
107
+
108
+ # セッションにセット
109
+ state["client"] = client
110
+ # state["assistant_id"] = assistant.id
111
+ state["assistant_id"] = os.environ["ASSIST_ID"] # テスト中アシスタントは固定
112
+ state["thread_id"] = thread.id
113
+
114
+ if file:
115
+
116
+ # ファイル名取得
117
+ basename = os.path.basename(file)
118
+
119
+ if example_toid.get(basename):
120
+
121
+ # サンプルの場合は用意したIDをセット
122
+ file_id = example_toid.get(basename)
123
+
124
+ else:
125
+
126
+ # ファイルのアップ
127
+ # file_response = client.files.create(
128
+ # purpose="assistants",
129
+ # file=open(file,"rb"),
130
+ # )
131
+
132
+ # if file_response.status != 'processed':
133
+
134
+ # # 失敗時
135
+ # err_msg = "ファイルのアップロードに失敗しました"
136
+
137
+ # else
138
+ # # ファイルのIDをセット
139
+ # file_id = file_response.id
140
+
141
+ # file_id = "file-0Ly64DA2jzE9mOFYayOKJJK0"
142
+ # file_id = "file-aVnVcpEVpsy77xQ8SlTp1WoX" # ライ麦
143
+
144
+ # file_id = "file-HFCaJbf3k7j0fhBqh1Rwf2VV" # 練馬区
145
+ file_id = ""
146
+
147
+ # print(file_id)
148
+
149
+ return state, text, file, file_id, err_msg
150
+
151
+ def raise_exception(err_msg):
152
+ """ エラーの場合例外を起こす関数 """
153
+
154
+ if err_msg != "":
155
+ raise Exception("これは入力チェックでの例外です。")
156
+
157
+ return
158
+
159
+
160
+ def add_history(history, text, file_id):
161
+ """ Chat履歴"history"に追���を行う関数 """
162
+
163
+ # print("前:")
164
+ # print(history)
165
+
166
+ err_msg = ""
167
+ new_row_flg = False
168
+
169
+ # 新しい行を追加するか判定
170
+ # if len(history) == 0:
171
+
172
+ # new_row_flg = True
173
+
174
+ # elif history[-1][0] is not None:
175
+
176
+ # # 前回がアシスタントでない場合も追加
177
+ # new_row_flg = True
178
+
179
+ new_row_flg = True
180
+
181
+ if file_id is None or file_id == "":
182
+
183
+ if new_row_flg:
184
+
185
+ # テキストだけの場合そのまま追加
186
+ history = history + [(text, None)]
187
+ else:
188
+ history[-1][0] = text
189
+
190
+ elif file_id is not None:
191
+
192
+ if new_row_flg:
193
+
194
+ # ファイルがあればファイルIDとテキストを追加
195
+ history = history + [("file:" + file_id, DUMMY)]
196
+ history = history + [(text, None)]
197
+
198
+ else:
199
+ history[-1][0] = "file:" + file_id
200
+ history = history + [(text, None)]
201
+
202
+ print(history)
203
+
204
+ # テキストだけ初期化
205
+ new_text = gr.Textbox(value="", interactive=True)
206
+
207
+ return history, new_text, err_msg
208
+
209
+
210
+ def bot(state, history, file_id):
211
+
212
+ err_msg = ""
213
+ image_file = None
214
+ ant_file = None
215
+ # new_row_flg = False
216
+
217
+ # セッション情報取得
218
+ system_prompt = state["system_prompt"]
219
+ client = state["client"]
220
+ assistant_id = state["assistant_id"]
221
+ thread_id = state["thread_id"]
222
+ msg_id = state["last_msg_id"]
223
+ code_mode = state["code_mode"]
224
+
225
+ print("system_prompt")
226
+
227
+ if file_id is None or file_id == "":
228
+
229
+ # ファイルがない場合
230
+ message = client.beta.threads.messages.create(
231
+ thread_id=thread_id,
232
+ role="user",
233
+ content=history[-1][0],
234
+ )
235
+ else:
236
+
237
+ # ファイルがあるときはIDをセット
238
+ message = client.beta.threads.messages.create(
239
+ thread_id=thread_id,
240
+ role="user",
241
+ content=history[-1][0],
242
+ file_ids=[file_id]
243
+ )
244
+
245
+ print(message)
246
+
247
+ # RUNスタート
248
+ run = client.beta.threads.runs.create(
249
+ thread_id=thread_id,
250
+ assistant_id=assistant_id,
251
+ instructions=system_prompt
252
+ )
253
+
254
+ # "completed"となるまで繰り返す(指定秒おき)
255
+ for i in range(0, MAX_TRIAL, 1):
256
+
257
+ if i > 0:
258
+ time.sleep(INTER_SEC)
259
+
260
+ # メッセージ受け取り
261
+ run = client.beta.threads.runs.retrieve(
262
+ thread_id=thread_id,
263
+ run_id=run.id
264
+ )
265
+
266
+ # 前回のメッセージより後を昇順で取り出す
267
+ messages = client.beta.threads.messages.list(
268
+ thread_id=thread_id,
269
+ after=msg_id,
270
+ order="asc"
271
+ )
272
+
273
+ # print(msg_id)
274
+ # print(messages.data)
275
+
276
+ msg_log = client.beta.threads.messages.list(
277
+ thread_id=thread_id,
278
+ # after=msg_id,
279
+ order="asc"
280
+ )
281
+
282
+ print(msg_log)
283
+
284
+ # messageを取り出す
285
+ for msg in messages:
286
+
287
+ msg_id = msg.id
288
+
289
+ if msg.role == "assistant":
290
+
291
+ for content in msg.content:
292
+
293
+ res_text = ""
294
+ file_id = ""
295
+ ant_file = None
296
+
297
+ cont_dict = content.model_dump() # 辞書型に変換
298
+
299
+ ct_image_file = cont_dict.get("image_file")
300
+
301
+ if ct_image_file:
302
+
303
+ # imageファイルがあるならIDセット
304
+ res_file_id = ct_image_file.get("file_id")
305
+
306
+ # ファイルをダウンロード
307
+ image_file = file_download(client, res_file_id, IMG_FOLDER , ".png")
308
+
309
+ if image_file is None:
310
+
311
+ err_msg = "ファイルのダウンロードに失敗しました。"
312
+
313
+ else:
314
+
315
+ print("画像ファイル追加")
316
+
317
+ res_text = IMG_MSG
318
+
319
+ history = history + [[None, res_text]]
320
+
321
+ else:
322
+
323
+ # 画像がないならテキスト取得
324
+ res_text = cont_dict["text"].get("value")
325
+
326
+ # 注釈(参照ファイル)ががある場合取得
327
+ if len(cont_dict.get("text").get("annotations")) > 0:
328
+
329
+ ct_ant = cont_dict.get("text").get("annotations")
330
+
331
+ if ct_ant[0].get("file_path") is not None:
332
+
333
+ # 参照ファイルのID取得
334
+ ant_file_id = ct_ant[0].get("file_path").get("file_id")
335
+
336
+ if ct_ant[0].get("text") is not None:
337
+
338
+ # ファイル形式(拡張子)取得
339
+ ext = "." + ct_ant[0].get("text")[ct_ant[0].get("text").rfind('.') + 1:]
340
+
341
+ # ファイルダウンロード
342
+ ant_file = file_download(client, ant_file_id, ANT_FOLDER, ext)
343
+
344
+ if ant_file is None:
345
+
346
+ err_msg = "参照ファイルのダウンロードに失敗しました。"
347
+
348
+ else:
349
+
350
+ # 参照ファイルがある旨のメッセージを追加
351
+ res_text = res_text + "\n\n" + ANT_MSG
352
+
353
+ print(res_text)
354
+
355
+ if res_text != "":
356
+
357
+ # Chat画面更新
358
+ if history[-1][1] is not None:
359
+
360
+ # 新しい行を追加
361
+ history = history + [[None, res_text]]
362
+ else:
363
+
364
+ history[-1][1] = res_text
365
+
366
+ yield history, image_file, ant_file, err_msg
367
+
368
+ print(run.status)
369
+
370
+ state["last_msg_id"] = msg_id
371
+
372
+ # 完了なら終了
373
+ if run.status == "completed":
374
+
375
+ if not code_mode:
376
+ break
377
+ else:
378
+
379
+ # コードモードがONの場合
380
+ run_steps = client.beta.threads.runs.steps.list(
381
+ thread_id=thread_id, run_id=run.id
382
+ )
383
+
384
+ # コードを取得
385
+ input_code = get_code(run_steps)
386
+
387
+ if len(input_code) > 0:
388
+
389
+ for code in input_code:
390
+
391
+ code = "[input_code]\n\n" + code
392
+
393
+ # コードを追加
394
+ history = history + [[None, code]]
395
+
396
+ yield history, image_file, ant_file, err_msg
397
+
398
+ break
399
+
400
+ if run.status == "failed":
401
+
402
+ # エラーとして終了
403
+ err_msg = "※メッセージ取得に失敗しました。"
404
+ return history, image_file, ant_file, err_msg
405
+
406
+ if i == MAX_TRIAL:
407
+
408
+ # エラーとして終了
409
+ err_msg = "※メッセージ取得の際にタイムアウトしました。"
410
+ return history, image_file, ant_file, err_msg
411
+
412
+
413
+ def get_code(run_steps):
414
+
415
+ input_code = []
416
+
417
+ for data in run_steps.data:
418
+
419
+ if isinstance(data.step_details, ToolCallsStepDetails):
420
+
421
+ for tool_call in data.step_details.tool_calls:
422
+
423
+ input_code.append(tool_call.code_interpreter.input)
424
+
425
+ return input_code
426
+
427
+
428
+ def file_download(client, file_id, folder, ext):
429
+ """ OpenAIからファイルをダウンロードしてパスを返す """
430
+ api_response = client.files.with_raw_response.retrieve_content(file_id)
431
+
432
+ if api_response.status_code == 200:
433
+
434
+ content = api_response.content
435
+
436
+ file_path = folder + "/" + file_id + ext
437
+
438
+ with open(file_path, 'wb') as f:
439
+ f.write(content)
440
+
441
+ return file_path
442
+
443
+ else:
444
+ return None
445
+
446
+
447
+ def finally_proc():
448
+ """ 最終処理用関数 """
449
+
450
+ new_up_file = gr.File(value=None, interactive = True)
451
+ new_file_id = gr.Textbox(value="")
452
+
453
+ return new_up_file, new_file_id
454
+
455
+
456
+ with gr.Blocks() as demo:
457
+
458
+ gr.Markdown("<h2>GPT Code Interpreter対応チャット</h2>")
459
+
460
+ # セッションの宣言
461
+ state = gr.State({
462
+ "system_prompt": SYS_PROMPT_DEFAULT,
463
+ "openai_key" : None,
464
+ "code_mode" : True,
465
+ "client" : None,
466
+ "assistant_id" : None,
467
+ "thread_id" : None,
468
+ "last_msg_id" : ""
469
+ })
470
+
471
+ with gr.Tab("Chat画面") as chat:
472
+
473
+ # 各コンポーネント定義
474
+ chatbot = gr.Chatbot(label="チャット画面")
475
+ text_msg = gr.Textbox(label="テキスト")
476
+ up_file = gr.File(label="ファイルアップロード", type="filepath",interactive = True)
477
+ gr.Examples(label="サンプルデータ", examples=examples, inputs=[up_file])
478
+ with gr.Row():
479
+ btn = gr.Button(value="送信")
480
+ # btn_download = gr.Button(value="画像のダウンロード") # 保留中
481
+ btn_clear = gr.ClearButton(value="リセット", components=[chatbot, text_msg, up_file, state])
482
+ sys_msg = gr.Textbox(label="システムメッセージ", interactive = False)
483
+ result_image = gr.Image(label="出力画像", type="filepath", interactive = False)
484
+ result_file = gr.File(label="出力ファイル", type="filepath",interactive = False)
485
+
486
+ # ファイルID保存用
487
+ file_id = gr.Textbox(visible=False)
488
+
489
+ # 送信ボタンクリック時の処理
490
+ bc = btn.click(init, [state, text_msg, up_file], [state, text_msg, up_file, file_id, sys_msg], queue=False).success(
491
+ raise_exception, sys_msg, None).success(
492
+ add_history, [chatbot, text_msg, file_id], [chatbot, text_msg, sys_msg], queue=False).success(
493
+ bot, [state, chatbot, file_id],[chatbot, result_image, result_file, sys_msg]).then(
494
+ finally_proc, None, [up_file, file_id], queue=False
495
+ )
496
+
497
+ # クリア時でもOpenAIKeyなどは再セット
498
+ # btn_clear.click(set_state, [openai_key, system_prompt, code_output, state], state)
499
+
500
+ # テキスト入力Enter時の処理
501
+ # txt_msg = text_msg.submit(respond, inputs=[text_msg, image, chatbot], outputs=[text_msg, image, chatbot])
502
+
503
+ with gr.Tab("設定") as set:
504
+ openai_key = gr.Textbox(label="OpenAI API Key")
505
+ # language = gr.Dropdown(choices=["Japanese", "English"], value = "Japanese", label="Language", interactive = True)
506
+ system_prompt = gr.Textbox(value = SYS_PROMPT_DEFAULT,lines = 5, label="Custom instructions", interactive = True)
507
+ # Enter不使用
508
+ code_output = gr.Dropdown(label="コード出力", choices=["OFF", "ON"], value = "ON", interactive = True)
509
+
510
+ # 設定タブからChatタブに戻った時の処理
511
+ chat.select(set_state, [openai_key, system_prompt, code_output, state], state)
512
+
513
+ demo.queue()
514
+
515
+ demo.launch(debug=True)