fudii0921 commited on
Commit
c0e1a34
·
verified ·
1 Parent(s): 8fdfe8a

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +310 -0
app.py ADDED
@@ -0,0 +1,310 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import cohere
3
+ import os
4
+ from dotenv import load_dotenv
5
+ from email.mime.text import MIMEText
6
+ import json
7
+
8
+ from qdrant_client.models import Distance, VectorParams
9
+ from qdrant_client import QdrantClient, models
10
+ import uuid
11
+ import base64
12
+ import requests
13
+
14
+ load_dotenv(verbose=True)
15
+
16
+ #sessuid = ""
17
+ state = gr.State({"loginuser": ""})
18
+
19
+ # Initialize Qdrant and Cohere clients
20
+ #client = QdrantClient(url=os.environ.get("QDRANT_URL"))
21
+ client = QdrantClient(url="os.environ.get("QDRANT_URL")", api_key="os.environ.get("QDRANT_API_KEY")")
22
+ cohere_client = cohere.Client(api_key=os.environ.get("COHERE_API_KEY")) # Add your Cohere API key here
23
+ co = cohere.ClientV2(api_key=os.environ.get("COHERE_API_KEY"))
24
+
25
+ def user_info(state):
26
+ #print("state:",state)
27
+ gr.Info("USER INFO: "+state["loginuser"])
28
+ #username = state["loginuser"]
29
+ #return username
30
+
31
+ def auth(user_name, password):
32
+ encoded = base64.b64encode(password.encode("utf-8"))
33
+
34
+ # APIエンドポイントのURL
35
+ url = "https://www.ryhintl.com/dbjson/getjson?sqlcmd=select userid from ku_credential where password = '" + encoded.decode("utf-8") + "'"
36
+
37
+ # GETリクエストの例
38
+ response = requests.get(url)
39
+ if response.status_code == 200:
40
+ credential_id = response.content.decode('utf-8')
41
+ parsed_data = json.loads(credential_id)
42
+
43
+ # useridを取得
44
+ taken_userid = parsed_data[0]["userid"]
45
+ if (taken_userid == user_name):
46
+ state.value["loginuser"] = user_name
47
+ return True # 認証成功
48
+ else:
49
+ return False
50
+
51
+ def process_invitees(state,input_json):
52
+ try:
53
+ # Parse the JSON input
54
+ invitees = json.loads(input_json)
55
+
56
+ # Generate embeddings using Cohere
57
+ response = cohere_client.embed(
58
+ texts=[
59
+ f"{note.get('kx_subject', '')}, {note.get('kx_creator', '')}, {note.get('kx_content', '')}, {note.get('kx_industry', '')}, {note.get('kx_kind', '')}, {note.get('kx_category', '')}, {note.get('kx_date', '')}"
60
+ for note in invitees
61
+ ],
62
+ model="embed-multilingual-v3.0",
63
+ input_type="search_document",
64
+ )
65
+
66
+ # Upload points to Qdrant
67
+ client.upload_points(
68
+ collection_name="knowledge_utility",
69
+ points=[
70
+ models.PointStruct(
71
+ id=uuid.uuid4().hex,
72
+ vector=embedding,
73
+ payload=note,
74
+ )
75
+ for note, embedding in zip(invitees, response.embeddings)
76
+ ]
77
+ )
78
+
79
+ return "Data uploaded successfully!"
80
+
81
+ except Exception as e:
82
+ return f"Error: {str(e)}"
83
+
84
+ # Function to send Gmail
85
+ def send_gmail(mail_from, mail_to, mail_subject, mail_body):
86
+ try:
87
+ sent_mails = f"From: {mail_from}\nTo: {mail_to}\nSubject: {mail_subject}\nBody:\n{mail_body}\n"
88
+ except Exception as e:
89
+ sent_mails = f"Error sending mail: {str(e)}"
90
+ return sent_mails
91
+
92
+ # Function to handle search query
93
+ def search(state,query: str):
94
+ state["userid"] = state["loginuser"]
95
+
96
+ global sent_mails
97
+ # Embed query using Cohere
98
+ response = cohere_client.embed(
99
+ texts=[query],
100
+ model="embed-multilingual-v3.0",
101
+ input_type="search_query",
102
+ )
103
+
104
+ # Query Qdrant collection for relevant points
105
+ results = client.query_points(
106
+ collection_name="knowledge_utility",
107
+ query=response.embeddings[0],
108
+ limit=1,
109
+ ).points
110
+
111
+ for result in results:
112
+ state["score"] = result.score
113
+
114
+ # Filter points based on similarity threshold
115
+ similarity_threshold = 0.1 # Example threshold for filtering
116
+ filtered_points = [point for point in results if point.score >= similarity_threshold]
117
+
118
+ #print("filtered_points:",filtered_points)
119
+
120
+ # Apply limit to the filtered points
121
+ final_limit = len(filtered_points) # Example limit
122
+ limited_points = filtered_points[:final_limit]
123
+ #print("finals:",final_limit,limited_points)
124
+
125
+ # Assuming `results` is a list of ScoredPoint objects
126
+ payload_list = []
127
+
128
+ # Iterate through the limited results and extract payloads
129
+ for point in limited_points:
130
+ # Access the payload attribute and append it to the list
131
+ print("point:",point)
132
+ payload_list.append(point.payload)
133
+
134
+ #print("payload_list:",payload_list)
135
+
136
+ # Template for the invitation letter
137
+ template = ""
138
+
139
+ '''print("kx_subject:",payload_list[0]["kx_subject"])
140
+ # Generate invitation letters
141
+ letters = []
142
+ for invitee in payload_list:
143
+ # Replace placeholders in the template with actual invitee information
144
+ letter = template.format(
145
+ 表題=payload_list[0]["kx_subject"],
146
+ コンテンツ=payload_list[0]["kx_content"],
147
+ 業種=payload_list[0]["kx_industry"],
148
+ 業界=payload_list[0]["kx_kind"],
149
+ 作成者=payload_list[0]["kx_creator"]
150
+ )
151
+
152
+ letters.append(letter)
153
+
154
+ print("letters:",letters)
155
+
156
+ # Print generated letters
157
+ invitations = ""
158
+ for idx, letter in enumerate(letters, start=1):
159
+ invitations += f"Invitation Letter {idx}:\n{letter}\n"'''
160
+
161
+ # Prepare results in a user-friendly format
162
+ formatted_results = [
163
+ f"kx_subject: {point.payload['kx_subject']}\nkx_content: {point.payload['kx_content']}\nkx_creator: {point.payload['kx_creator']}\nkx_industry: {point.payload['kx_industry']}\nkx_kind: {point.payload['kx_kind']}\nkx_category: {point.payload['kx_category']}\nkx_date: {point.payload['kx_date']}"
164
+ for point in results
165
+ ]
166
+
167
+ #print("formatted_results",formatted_results)
168
+ final_result = "\n\n".join(formatted_results)
169
+
170
+ res = co.chat(
171
+ model="command-a-03-2025",
172
+ messages=[
173
+ {
174
+ "role": "user",
175
+ "content": final_result+"を要約してください。 必ず、日本語で答えてください。",
176
+ }
177
+ ],
178
+ )
179
+ final = res.message.content[0].text
180
+
181
+ # Extract content between "---"
182
+ start_marker = "---"
183
+ end_marker = "---"
184
+ start_index = final.find(start_marker) + len(start_marker)
185
+ end_index = final.rfind(end_marker)
186
+
187
+ return final,state["score"]
188
+
189
+ # Gradio Blocks Interface
190
+ with gr.Blocks(css="footer {visibility: hidden;} .custom-btn {width: 150px; height: 30px; background-color: lightblue; border-radius: 10px; font-size: 12px; color: #3C82F6;} #header {display: flex; justify-content: space-between; align-items: center; font-size: 24px; font-weight: bold;} #logo {width: 50px; height: 50px;}",title="Knowledge Utility",theme=gr.themes.Glass()) as ku:
191
+ state = gr.State({
192
+ "userid": "",
193
+ "score": 0
194
+ })
195
+
196
+ with gr.Column():
197
+ gr.HTML('<div id="header"><span>🛡️ Knowledge Utility</span><img id="logo" src="https://www.ryhintl.com/images/ryhlogo/ryhlogo.png" width="64" height="64" alt="Logo"></div>')
198
+ gr.Markdown("# ナレッジ・エージェント")
199
+ gr.Markdown("📧 ベクターDBに保存されている知識ベースのインベントリを使用して知識共有します。")
200
+ user_btn = gr.Button("ユーザー情報", elem_classes=["custom-btn"])
201
+
202
+ user_btn.click(fn=user_info, inputs=[state], outputs=None)
203
+
204
+
205
+ with gr.Sidebar(open=False):
206
+ gr.HTML("""
207
+ <!DOCTYPE html>
208
+ <html lang="ja">
209
+ <head>
210
+ <meta charset="UTF-8">
211
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
212
+ <title>Knowledge Utility</title>
213
+ <style>
214
+ body {
215
+ font-family: Arial, sans-serif;
216
+ line-height: 1.6;
217
+ background-color: #f4f4f9;
218
+ color: #333;
219
+ margin: 0;
220
+ padding: 0;
221
+ }
222
+ header {
223
+ background: #0078d7;
224
+ color: #fff;
225
+ padding: 1rem 0;
226
+ text-align: center;
227
+ }
228
+ section {
229
+ max-width: 800px;
230
+ margin: 2rem auto;
231
+ padding: 1rem;
232
+ background: #fff;
233
+ border-radius: 5px;
234
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
235
+ }
236
+ h1, h2, h3 {
237
+ color: #0078d7;
238
+ }
239
+ ul {
240
+ padding-left: 1.5rem;
241
+ }
242
+ footer {
243
+ text-align: center;
244
+ padding: 1rem 0;
245
+ margin-top: 2rem;
246
+ background: #0078d7;
247
+ color: white;
248
+ }
249
+ </style>
250
+ </head>
251
+ <body>
252
+ <header>
253
+ <h1 style="color: white;">Knowledge Utility</h1>
254
+ <p style="color: white;">知識をシェアし、成長を加速させる。</p>
255
+ </header>
256
+ <section>
257
+ <h2>Knowledge Utilityとは?</h2>
258
+ <p>
259
+ Knowledge Utilityは、企業や個人が知識を効果的に共有し、成長を促進するためのプラットフォームです。
260
+ データ、アイデア、専門知識をシームレスに交換し、新たな価値を生み出します。
261
+ </p>
262
+ <h2>主な機能</h2>
263
+ <ul>
264
+ <li><strong>情報の検索:</strong> 高速かつ正確なクエリによる知識の取得。</li>
265
+ <li><strong>データの登録:</strong> 個人または企業の資産をデータベースに統合。</li>
266
+ <li><strong>コラボレーション:</strong> チームやコミュニティ間の知識交換を促進。</li>
267
+ </ul>
268
+ <h2>メリット</h2>
269
+ <p>
270
+ Knowledge Utilityを活用することで、効率の向上、意思決定のスピードアップ、そして
271
+ 組織の成長が期待できます。
272
+ </p>
273
+ </section>
274
+ <footer>
275
+ <p>&copy; 2025 Knowledge Utility Platform. All rights reserved.</p>
276
+ </footer>
277
+ </body>
278
+ </html>
279
+ """)
280
+
281
+ with gr.Tab("KU 検索"):
282
+ with gr.Row():
283
+ query_input = gr.Textbox(
284
+ label="クエリ",
285
+ placeholder="例)物流・流通業界向けの提案書を内容を教えてください。",
286
+ info="例)物流・流通業界向けの提案書を内容を教えてください。",
287
+ value="経営デジタル・トランスフォーメーション関連のプロジェクトの提案書を書こうと思っています。参考できる事例を教えてください。",
288
+ lines=2,
289
+ )
290
+ with gr.Column():
291
+ search_button = gr.Button("実行", elem_classes=["custom-btn"])
292
+ clear_button = gr.Button("クリア", elem_classes=["custom-btn"])
293
+
294
+ result_output = [gr.Textbox(label="結果", show_copy_button=True),gr.Textbox(label="スコア")]
295
+
296
+ # Button click events
297
+ search_button.click(fn=search, inputs=[state,query_input], outputs=result_output)
298
+ clear_button.click(lambda: "", None, result_output)
299
+
300
+ with gr.Tab("KU インベントリ登録"):
301
+ with gr.Row():
302
+ input_text = gr.Textbox(label="KU JSON Payroll", lines=10, placeholder="Paste your JSON Payroll here...", info="""[{"kx_subject": "中古車販売における現状と問題点", "kx_creator": "richardhuh0629@gmail.com", "kx_content": "事前情報の収集: 顧客動向、問題・課題の想定、3C分析を通じて仮説を策定する。企業動向、顧客動向、競合動向を分析し、仮説を立案する。仮説提案営業の商談フロー: あいさつ、自社紹介、詳細ヒアリング、仮説検証、解決策の提案、ディスカッション、宿題の出し合い、あいさつのステップを踏む。効果的な商談の進め方: 訪問の趣旨を伝え、基本的な質問をし、相手に話させる。仮説をぶつけ、次回の日付と宿題を決める。ヒアリングの技術: 荷主担当者と営業担当者の知識の差を理解し、必要に応じて役割を分担する。ロジスティクスフローを描き、詳細な設問項目を作成する。", "kx_industry": "物流・流通", "kx_kind": "小売", "kx_category": "提案書", "kx_date": "2025/06/02"}]""")
303
+ output_text = gr.Textbox(label="Result")
304
+ with gr.Row():
305
+ submit_button = gr.Button("実行", elem_classes=["custom-btn"])
306
+
307
+ submit_button.click(process_invitees, inputs=[state,input_text], outputs=output_text)
308
+
309
+ # Launch the app
310
+ ku.launch(auth=auth,favicon_path="favicon.ico")