fudii0921 commited on
Commit
ae062d9
·
verified ·
1 Parent(s): d9c3aee

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +637 -0
app.py ADDED
@@ -0,0 +1,637 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import re
3
+ import hashlib
4
+ import mysql.connector as mydb
5
+ import time
6
+
7
+ #import cohere
8
+ import os
9
+ from dotenv import load_dotenv
10
+
11
+ import numpy as np
12
+ import psycopg2
13
+ from google import genai
14
+ from google.genai import types
15
+
16
+ import uuid
17
+ import base64
18
+ import requests
19
+ import asyncio
20
+ import random
21
+ import pandas as pd
22
+ from docx import Document
23
+ from llama_parse import LlamaParse
24
+ from llama_index.core import SimpleDirectoryReader
25
+
26
+ load_dotenv(verbose=True)
27
+
28
+ client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
29
+
30
+ chat_history = []
31
+ intreme = []
32
+
33
+ basic_format = ""
34
+
35
+ class DoSwitch:
36
+ def __init__(self):
37
+ # 状態(state)をインスタンス変数として保持
38
+ self.is_logged = False
39
+ self.first_exec = False
40
+ self.lastlog = ""
41
+
42
+ def log_on(self):
43
+ self.is_logged = True
44
+
45
+ def log_oout(self):
46
+ self.log_on = False
47
+
48
+ def first_executed(self):
49
+ self.first_exec = True
50
+
51
+ my_switch = DoSwitch()
52
+
53
+ def clean_text(text):
54
+ # 改行とタブを削除
55
+ return text.replace('\n', '').replace('\t', '').replace(' ', '')
56
+
57
+ def update_file_type(file):
58
+ global filepath
59
+ filepath = file
60
+ if file is not None:
61
+ # アップロードされたファイルの拡張子を取得
62
+ _, ext = os.path.splitext(file.name)
63
+ return ext
64
+ return ""
65
+
66
+
67
+ def respond(ctype, msg, username, response_check):
68
+ print("response_check:",response_check)
69
+ if response_check == True:
70
+ prompt = f"""「答え」をウェブで調べて、必ず、日本語で答えてください。
71
+ 「答え」={msg}
72
+ """
73
+ else:
74
+ prompt = f"""以下の「レポート」を「基本形」に沿って正しく明記されているかをチェックし、レポートがどれ位「基本形」に沿った形でカバーしているかを教えてください。尚、漏れている項目を表示し、その内容をウェブから検索し、アドバイスしてください。最終的に内容がわかりやすかったか否かを教えてください。「基本形」にどれ位沿っているかも教えてください。必ず、日本語で答えてください。
75
+ 「レポート」={msg}
76
+ 「基本形」={basic_format}
77
+ """
78
+
79
+ gresponse = client.models.generate_content(
80
+ model="gemini-2.5-flash",
81
+ contents=[prompt]
82
+ )
83
+ summary = gresponse.text
84
+
85
+ print("summary1:",summary)
86
+
87
+ return summary
88
+
89
+
90
+ def validate_username(username):
91
+ if len(username) < 4:
92
+ return "ユーザー名は4文字以上である必要があります"
93
+ if not re.match("^[a-zA-Z0-9_]+$", username):
94
+ return "ユーザー名には文字、数字、アンダースコアのみ使用できます"
95
+ return None
96
+
97
+ def validate_email(email):
98
+ if not re.match(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$", email):
99
+ return "有効なメールアドレスを入力してください"
100
+ return None
101
+
102
+ def validate_password(password):
103
+ if len(password) < 8:
104
+ return "パスワードは8文字以上でなければなりません"
105
+ if not any(char.isdigit() for char in password):
106
+ return "パスワードには少なくとも1つの数字を含める必要があります"
107
+ if not any(char.isupper() for char in password):
108
+ return "パスワードには少なくとも1つの大文字を含める必要があります"
109
+ return None
110
+
111
+ def validate_phone(phone):
112
+ if phone and not re.match(r"^\+?[0-9\s\-]+$", phone):
113
+ return "有効な電話番号を入力してください"
114
+ return None
115
+
116
+ def hash_password(password):
117
+ return hashlib.sha256(password.encode()).hexdigest()
118
+
119
+
120
+ def login_user(username, password):
121
+ conn = mydb.connect(
122
+ host='www.ryhintl.com',
123
+ port='36000',
124
+ user='smairuser',
125
+ password='smairuser',
126
+ database='smair'
127
+ )
128
+ c = conn.cursor()
129
+ hashed_pw = hash_password(password)
130
+ sqlcmd = "SELECT * FROM gyoseki_users WHERE username = '"+username+"' AND password = '"+hashed_pw+"'"
131
+ c.execute(sqlcmd)
132
+
133
+ user = c.fetchone()
134
+ conn.close()
135
+
136
+ if user:
137
+ return True, user
138
+ return False, "ユーザー名またはパスワードが無効です"
139
+
140
+
141
+ def process_logout():
142
+ time.sleep(1)
143
+ return gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)
144
+
145
+ # Login Logic
146
+ def process_login(username, password, current_user_info_state):
147
+ username_error = validate_username(username)
148
+ password_error = validate_password(password)
149
+
150
+ if username_error:
151
+ return gr.update(value=f"<p class='error-message'>{username_error}</p>"), False, None, None, gr.update(visible=True), gr.update(visible=False)
152
+ elif password_error:
153
+ return gr.update(value=f"<p class='error-message'>{password_error}</p>"), False, None, None, gr.update(visible=True), gr.update(visible=False)
154
+ else:
155
+ success, result = login_user(username, password)
156
+ if success:
157
+ user_info = {
158
+ "id": result[0],
159
+ "username": result[1],
160
+ "email": result[2],
161
+ "phone": result[4],
162
+ "basic_format": result[5]
163
+ }
164
+
165
+ uid = result[5]
166
+
167
+ conn = mydb.connect(
168
+ host='www.ryhintl.com',
169
+ port='36000',
170
+ user='smairuser',
171
+ password='smairuser',
172
+ database='smair'
173
+ )
174
+ c = conn.cursor()
175
+
176
+ sqlcmd = "SELECT contents FROM gyoseki_basic_format WHERE id = "+str(uid)
177
+ c.execute(sqlcmd)
178
+
179
+ content = c.fetchone()
180
+ global basic_format
181
+ basic_format = content
182
+ conn.close()
183
+
184
+ return gr.update(value="<p class='success-message'></p>"), True, username, user_info, gr.update(visible=False), gr.update(visible=True), gr.update(visible=True), gr.update(visible=False)
185
+ #return gr.update(value="<p class='success-message'></p>"), True, username, user_info, gr.update(visible=False), gr.update(visible=True)
186
+ else:
187
+ #return gr.update(visible=False), gr.update(visible=True)
188
+ return gr.update(value=f"<p class='error-message'>{result}</p>"), False, None, None, gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(visible=True)
189
+ #return gr.update(value=f"<p class='error-message'>{result}</p>"), False, None, None, gr.update(visible=True), gr.update(visible=False)
190
+
191
+
192
+ def filecomp_change(prompt):
193
+ if prompt == None:
194
+ return gr.update(visible=False),gr.update(visible=True),gr.update(visible=True)
195
+ else:
196
+ return gr.update(visible=True),gr.update(visible=True),gr.update(visible=False)
197
+
198
+ def summary_change(prompt):
199
+ if len(prompt) == 0:
200
+ return gr.update(visible=False)
201
+ else:
202
+ return gr.update(visible=True)
203
+
204
+
205
+ def prompt_change(prompt):
206
+ if len(prompt["files"]) > 0:
207
+ print("cnt:",len(prompt["files"]))
208
+ for x in prompt["files"]:
209
+ file_path = prompt['files'][0]
210
+ print("file path",file_path)
211
+ return gr.update(visible=False),gr.update(visible=True),gr.update(visible=True)
212
+ else:
213
+ print("prompt:",prompt["text"])
214
+ return gr.update(visible=True),gr.update(visible=False),gr.update(visible=True)
215
+
216
+
217
+ def show_tab_1():
218
+ return gr.update(visible=True), gr.update(visible=False), gr.update(visible=False)
219
+
220
+ def show_tab_2():
221
+ return gr.update(visible=False), gr.update(visible=True), gr.update(visible=False)
222
+
223
+ def show_tab_3():
224
+ return gr.update(visible=False), gr.update(visible=False), gr.update(visible=True)
225
+
226
+ def embed(texts, input_type):
227
+ # 改行または句点で分割(任意で調整可能)
228
+ if isinstance(texts, str):
229
+ inputs = [t.strip() for t in texts.split("\n") if t.strip()]
230
+ else:
231
+ inputs = texts
232
+
233
+ result = client.models.embed_content(
234
+ model="gemini-embedding-001",
235
+ contents=inputs,
236
+ config=types.EmbedContentConfig(output_dimensionality=1024)
237
+ )
238
+
239
+ # 結果を整形して表示
240
+ formatted = ""
241
+ for i, embedding in enumerate(result.embeddings):
242
+ #formatted += f"Embedding (Array{i}: {embedding.values} \n\n"
243
+ formatted += f"{embedding.values}"
244
+ return formatted
245
+
246
+
247
+ def summarize_text(long_text, username, summarize_text):
248
+
249
+ if not long_text:
250
+ return "要約するテキストがありません。"
251
+
252
+ prompt = f"次の文章をuserとassistantに分けて的確に要約してください:\n{long_text}"
253
+ gresponse = client.models.generate_content(
254
+ model="gemini-2.5-flash",
255
+ contents=[prompt]
256
+ )
257
+ summary = gresponse.text
258
+
259
+ if (summarize_text == '保存'):
260
+
261
+ response = embed(summary,"search_document")
262
+
263
+ embedding_str = response
264
+
265
+ conn = psycopg2.connect(
266
+ dbname="smair",
267
+ user="smairuser",
268
+ password="smairuser",
269
+ host="www.ryhintl.com",
270
+ port=10629
271
+ )
272
+
273
+ cur = conn.cursor()
274
+ sql = "INSERT INTO dailog_logs (userid, content, embedding) VALUES (%s, %s, %s)"
275
+ cur.execute(sql, (username, summary, f"{embedding_str}"))
276
+ conn.commit()
277
+ cur.close()
278
+ conn.close()
279
+ return summary
280
+ else:
281
+ return summary
282
+
283
+
284
+ def generate_summary(input_text, username, summary_save):
285
+ if not username:
286
+ return "ログインしてください。"
287
+
288
+ summary = summarize_text(input_text, username, summary_save)
289
+ return summary
290
+
291
+ def tnews():
292
+ res = client.models.generate_content(
293
+ model="gemini-2.5-flash",
294
+ contents=["東証のtopixに関するニュースを教えてください。必ず、日本語で答えてください。"]
295
+ )
296
+ return res.text
297
+
298
+
299
+ def generate_response(dtype, file_name, file_type, msg, username, report_check):
300
+
301
+ #if (file_name == None): # Should not happen if UI is correctly managed
302
+ if (msg == '' and file_name == ''): # Should not happen if UI is correctly managed
303
+ ret = []
304
+ ret.append(["レポートをアップロードしてください。","Please Upload report."])
305
+ yield ret
306
+ elif (msg == '' and file_name != ''):
307
+
308
+ if (my_switch.first_exec == True):
309
+ intreme.append(["レポートを処理中...",tnews()])
310
+ yield intreme
311
+
312
+ parser = LlamaParse(
313
+ api_key=os.environ.get("LLAMA_API_KEY"),
314
+ language="ja",
315
+ high_res_ocr=True,
316
+ user_prompt="提供された文書はスライドである。1ページにはファイルのタイトル、2ページは目次となっており、それ以降のページは各ページごとの副題を持つ。資料は、テキスト、図、表、グラフ、イラストを含む。",
317
+ result_type="markdown" # "markdown" または "text" が選択可能
318
+ )
319
+
320
+ file_extractor = {file_type: parser}
321
+ documents = SimpleDirectoryReader(input_files=[file_name], file_extractor=file_extractor, recursive=False).load_data()
322
+
323
+ print("documents:",documents)
324
+ texts = [doc.text for doc in documents]
325
+ print("texts:",texts)
326
+
327
+ combined_text = clean_text(texts[0])
328
+ msg = texts[0]
329
+
330
+ bot_message = respond(file_type, msg, username, report_check)
331
+ print("botmsg:",bot_message)
332
+ chat_history.append([msg, bot_message])
333
+ intreme.clear()
334
+ yield chat_history
335
+ else:
336
+ #gotresp = requests.get('')
337
+ conn = psycopg2.connect(
338
+ dbname="smair",
339
+ user="smairuser",
340
+ password="smairuser",
341
+ host="www.ryhintl.com",
342
+ port=10629
343
+ )
344
+
345
+ cur = conn.cursor()
346
+ sql = "select content from dailog_logs where userid = '"+username+"'"
347
+ cur.execute(sql)
348
+ plog = cur.fetchone()
349
+ conn.close()
350
+
351
+ my_switch.first_exec = True
352
+
353
+ my_switch.lastlog = plog
354
+ prompt = f"""「前回の会話ログ」でユーザーの予測や仮説などから結果を核にする項目があれば、確認する質問を列挙してください。例えば、ハイブリッド車の販売が堅調でコスト削減効果が期待できることに言及したが、具体的な過去のコストや利益率の推移データは提示せず、トヨタ自動車の公式財務報告書などを参照するよう促した。などについてハイブリッド車の販売好調がコスト増加抑制に寄与しているという当初の推測について、その後、何か追加で確認できた点はありますか?」のように質問を列挙してください。
355
+ 「前回の会話ログ」={my_switch.lastlog}
356
+ """
357
+ gresponse = client.models.generate_content(
358
+ model="gemini-2.5-flash",
359
+ contents=[prompt]
360
+ )
361
+ lastqa = gresponse.text
362
+ msg = lastqa
363
+
364
+ intreme.append(["レポートを処理中...",lastqa])
365
+ #yield intreme
366
+
367
+ '''parser = LlamaParse(
368
+ api_key=os.environ.get("LLAMA_API_KEY"),
369
+ language="ja",
370
+ high_res_ocr=True,
371
+ user_prompt="提供された文書はスライドである。1ページにはファイルのタイトル、2ページは目次となっており、それ以降のページは各ページごとの副題を持つ。資料は、テキスト、図、表、グラフ、イラストを含む。",
372
+ result_type="markdown" # "markdown" または "text" が選択可能
373
+ )
374
+
375
+ file_extractor = {file_type: parser}
376
+ documents = SimpleDirectoryReader(input_files=[file_name], file_extractor=file_extractor, recursive=False).load_data()
377
+
378
+ texts = [doc.text for doc in documents]
379
+
380
+ combined_text = clean_text(texts[0])
381
+ msg = texts[0]'''
382
+
383
+ #bot_message = respond(file_type, msg, username, report_check) + "\n" + lastqa
384
+ bot_message = respond(file_type, msg, username, report_check)
385
+ chat_history.append([msg, bot_message])
386
+ intreme.clear()
387
+ yield chat_history
388
+
389
+ else:
390
+ intreme.append(["レポートを処理中...",tnews])
391
+ yield intreme
392
+
393
+ bot_message = respond(file_type, msg, username, report_check)
394
+ chat_history.append([msg, bot_message])
395
+ intreme.clear()
396
+ yield chat_history
397
+
398
+
399
+
400
+
401
+ def summary_change(prompt):
402
+ if len(prompt) == 0:
403
+ return gr.update(visible=False)
404
+ else:
405
+ return gr.update(visible=True)
406
+
407
+
408
+
409
+
410
+
411
+ with gr.Blocks(title="Fund Manager Academic Buddy", css="""footer {visibility: hidden;} #header {display: flex; justify-content: space-between; align-items: center; font-size: 24px; font-weight: bold;} #logo {width: 50px; height: 50px;}
412
+ .gradio-container {
413
+ background-color: #f8f9fa;
414
+ /*width: 100%;
415
+ height: 100%;
416
+ background-image: url('https://images.unsplash.com/photo-1527181152855-fc03fc7949c8?auto=format&w=1000&dpr=2');
417
+ background-size: cover;
418
+ background-repeat: no-repeat;
419
+ background-position: center center;*/
420
+ }
421
+ .main {
422
+ background-color: #f8f9fa;
423
+ }
424
+ .logo-container {
425
+ position: absolute;
426
+ top: 1px;
427
+ left: 20px;
428
+ z-index: 1000;
429
+ }
430
+ .logo-container img {
431
+ height: 30px;
432
+ width: auto;
433
+ }
434
+ .title {
435
+ font-size: 1.5rem;
436
+ font-weight: 700;
437
+ color: #2c3e50;
438
+ text-align: center;
439
+ margin-bottom: 1.5rem;
440
+ }
441
+ .subtitle {
442
+ font-size: 0.1rem;
443
+ color: #7f8c8d;
444
+ text-align: center;
445
+ margin-bottom: 2rem;
446
+ }
447
+
448
+ .rcard {
449
+ background: #000055;
450
+ border-radius: 15px;
451
+ padding: 2rem;
452
+ box-shadow: 0 10px 20px rgba(0,0,0,0.1);
453
+ margin-bottom: 1rem;
454
+ height: 650px;
455
+ overflow: hidden;
456
+ }
457
+
458
+ .card {
459
+ background: white;
460
+ border-radius: 15px;
461
+ padding: 2rem;
462
+ box-shadow: 0 10px 20px rgba(0,0,0,0.1);
463
+ margin-bottom: 1rem;
464
+ }
465
+ .success-message {
466
+ color: #27ae60;
467
+ text-align: center;
468
+ margin-top: 1rem;
469
+ }
470
+ .error-message {
471
+ color: #e74c3c;
472
+ text-align: center;
473
+ margin-top: 1rem;
474
+ }
475
+ .footer {
476
+ text-align: center;
477
+ margin-top: 1rem;
478
+ color: #95a5a6;
479
+ font-size: 0.8rem;
480
+ }
481
+ .avatar {
482
+ width: 50px;
483
+ height: 50px;
484
+ border-radius: 50%;
485
+ margin: 0 auto 1rem auto;
486
+ display: block;
487
+ object-fit: cover;
488
+ border: 3px solid #4a90e2;
489
+ }
490
+
491
+ .avatar:hover {
492
+ transform: scale(1.2);
493
+ border: 3px solid #4a90e2;
494
+ }
495
+ .gr-button {
496
+ width: 100%;
497
+ border-radius: 10px;
498
+ padding: 10px;
499
+ background-color: #4a90e2;
500
+ color: white;
501
+ border: none;
502
+ font-weight: 500;
503
+ transition: all 0.3s;
504
+ }
505
+ .gr-button:hover {
506
+ background-color: #357abd;
507
+ color: lightyellow;
508
+ transform: translateY(-2px);
509
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
510
+ }
511
+ .gr-textinput, .gr-textbox {
512
+ border-radius: 10px;
513
+ padding: 10px;
514
+ border: 1px solid #ced4da;
515
+ }
516
+ .my-custom-button {
517
+ background-color: transparent !important; /* 緑色 */
518
+ color: black !important;
519
+ padding: 10px 20px !important;
520
+ border: solid thin black !important;
521
+ border-radius: 5px !important;
522
+ cursor: pointer !important;
523
+ font-size: 16px !important;
524
+ width: 100%;
525
+ transition: background-color 0.3s ease !important;
526
+ }
527
+
528
+ .my-custom-button:hover {
529
+ background-color: #fff5ee !important; /* ホバー時の色 */
530
+ }
531
+ """) as demo:
532
+ # State variables
533
+ current_username = gr.State(None)
534
+ current_user_info = gr.State(None)
535
+ logged_in_state = gr.State(False)
536
+
537
+ with gr.Sidebar(position="left", open=True):
538
+ gr.Markdown("©️ FUND MANAGER BUDDY 2025")
539
+ signin = gr.Button("サインイン", visible=True, elem_classes=["my-custom-button"], icon="https://img.icons8.com/fluency/48/azure-1.png")
540
+ query = gr.Button("クエリー", visible=False, elem_classes=["my-custom-button"], icon="https://img.icons8.com/fluency/48/orthogonal-view.png")
541
+ smry = gr.Button("ダイアログ・サマリー", visible=False, elem_classes=["my-custom-button"], icon="https://img.icons8.com/3d-fluency/48/domain.png")
542
+
543
+ #with gr.Tabs() as tabs:
544
+ # Set the first tab to be visible by default
545
+ with gr.Column("タブ1", visible=False, elem_classes="card") as b1:
546
+ signup_btn = gr.Button("サインアップ", elem_classes=["my-custom-button"], icon="https://img.icons8.com/color/48/000000/google-logo.png")
547
+ login_username = gr.Textbox(label="ユーザー名", placeholder="ユーザー名を入力してください")
548
+ login_password = gr.Textbox(label="パスワード", type="password", placeholder="パスワードを入力してください")
549
+ login_status = gr.Markdown("")
550
+ login_btn = gr.Button("サインイン")
551
+
552
+ login_btn.click(
553
+ process_login,
554
+ inputs=[login_username, login_password, current_user_info],
555
+ outputs=[login_status, logged_in_state, current_username, current_user_info, signin, query, smry, b1]
556
+ )
557
+
558
+ with gr.Column("タブ2", visible=False) as b2:
559
+ with gr.TabItem("クエリー"):
560
+ logout_btn = gr.Button("ログアウト")
561
+ dialog_ctype = gr.Dropdown(["デフォルト"], label="会話形式", value="デフォルト")
562
+
563
+ with gr.Row(visible=True) as filecomp:
564
+ file_input = gr.File(label="レポートをアップロード(PDF,pptx,xlsx,docx,txt,mdなど)")
565
+ file_type = gr.Textbox(label="ファイルタイプ")
566
+
567
+ with gr.Row(visible=True) as reportcomp:
568
+ report_check = gr.Checkbox(label="レポート質問", info="レポート質問に対する答えの時にチェックしてください。")
569
+ report_content = gr.Textbox(label="レポート", lines=10, show_copy_button=True)
570
+ '''report_content = gr.MultimodalTextbox(
571
+ interactive=True,
572
+ file_count="single",
573
+ placeholder="レポートの内容や質問を入力してください",
574
+ label="レポート",
575
+ lines=10,
576
+ show_label=True,
577
+ sources=["upload", "microphone"],
578
+ )'''
579
+
580
+ dialog_output = gr.Chatbot(label="対話履歴", height=400, show_copy_all_button=True)
581
+ dialog_submit_btn = gr.Button("生成", visible=True)
582
+
583
+ file_input.change(fn=update_file_type, inputs=file_input, outputs=file_type)
584
+
585
+ #file_input.change(
586
+ #filecomp_change,
587
+ #inputs=[file_input],
588
+ #outputs=[dialog_submit_btn, filecomp, reportcomp]
589
+ #)
590
+
591
+ report_content.change(
592
+ prompt_change,
593
+ #handle_change,
594
+ inputs=[report_content],
595
+ outputs=[dialog_submit_btn, filecomp, reportcomp]
596
+ )
597
+
598
+ dialog_submit_btn.click(
599
+ generate_response,
600
+ inputs=[dialog_ctype, file_input, file_type, report_content, current_username, report_check],
601
+ outputs=[dialog_output]
602
+ )
603
+
604
+ with gr.Column("タブ3", visible=False) as b3:
605
+ with gr.TabItem("ダイアログ・サマリー"):
606
+ summary_input = gr.Textbox(label="要約したいユーザー・ダイアログを入力", lines=5)
607
+ summary_save = gr.Dropdown(["保存","保存しない"], label="DB保存", value="保存しない")
608
+ summary_output = gr.Markdown(label="要約結果", height=400, show_copy_button=True)
609
+ summary_submit_btn = gr.Button("要約", visible=False)
610
+
611
+ summary_input.change(
612
+ summary_change,
613
+ inputs=[summary_input],
614
+ outputs=[summary_submit_btn]
615
+ )
616
+
617
+ summary_submit_btn.click(
618
+ generate_summary,
619
+ inputs=[summary_input, current_username, summary_save],
620
+ outputs=summary_output
621
+ )
622
+
623
+ signin.click(show_tab_1, inputs=None, outputs=[b1, b2, b3])
624
+ query.click(show_tab_2, inputs=None, outputs=[b1, b2, b3])
625
+ smry.click(show_tab_3, inputs=None, outputs=[b1, b2, b3])
626
+ logout_btn.click(
627
+ process_logout,
628
+ inputs=[],
629
+ outputs=[signin,query,smry,b2]
630
+ )
631
+ #with gr.Sidebar(position="left"):
632
+ #gr.Markdown("## サイドバー")
633
+ #gr.Button("サインイン", elem_classes=["my-custom-button"], icon="https://img.icons8.com/fluency/48/azure-1.png").click(show_tab_1, inputs=None, outputs=[b1, b2, b3])
634
+ #query = gr.Button("クエリー", visible=False, elem_classes=["my-custom-button"], icon="https://img.icons8.com/fluency/48/orthogonal-view.png").click(show_tab_2, inputs=None, outputs=[b1, b2, b3])
635
+ #smry = gr.Button("ダイアログ・サマリー", visible=False, elem_classes=["my-custom-button"], icon="https://img.icons8.com/3d-fluency/48/domain.png").click(show_tab_3, inputs=None, outputs=[b1, b2, b3])
636
+
637
+ demo.launch()