import gradio as gr import cohere import os from dotenv import load_dotenv from email.mime.text import MIMEText import json from huggingface_hub import list_models from qdrant_client.models import Distance, VectorParams from qdrant_client import QdrantClient, models import uuid import base64 import requests load_dotenv(verbose=True) # Initialize Qdrant and Cohere clients client = QdrantClient(url=os.environ.get("QDRANT_URL"), api_key=os.environ.get("QDRANT_API_KEY")) cohere_client = cohere.Client(api_key=os.environ.get("COHERE_API_KEY")) co = cohere.ClientV2(api_key=os.environ.get("COHERE_API_KEY")) '''# OAuthProfile example class OAuthProfile: def __init__(self, name, username, profile, picture): self.name = name self.username = username self.profile = profile self.picture = picture oauth_profile = OAuthProfile( name="", username="", profile="", picture="" )''' def greeting(profile: gr.OAuthProfile | None) -> str: if profile is None: return "⛔️" else: print("profile:",profile) state.value["loginuser"] = profile.name return f"ようこそ! {profile.name}さん" #if profile is None: #return "⛔️" #return f"ようこそ! {profile.name}さん" def list_private_models(profile: gr.OAuthProfile | None, oauth_token: gr.OAuthToken | None) -> tuple[str, gr.update, gr.update]: gr.Textbox(oauth_token) if oauth_token is None: state.value["loginuser"] = "HuggingFaceにログインしてください。" state.value["picture"] = "" return "HuggingFaceにログインしてください。", gr.update(visible=False), gr.update(visible=False) #, gr.update(visible=False) #models = [ #f"{model.id} ({'private' if model.private else 'public'})" #for model in list_models(author=profile.username, token=oauth_token.token) #] userinfo = f"""名前: {profile.name}さん\nID: {profile.username}\nプロファイル: {profile.profile}""" print("userinfo:",userinfo) state.value["loginuser"] = userinfo state.value["picture"] = profile.picture print("pic:",state.value["picture"],profile.picture) print("login-user:",state.value["loginuser"],userinfo) '''global oauth_profile oauth_profile = OAuthProfile( name=profile.name, username=profile.username, profile=profile.profile, picture=profile.picture )''' #return profile.username, gr.update(visible=True), gr.update(visible=True) #, gr.update(visible=True) return userinfo, gr.update(visible=True), gr.update(visible=True) #, gr.update(visible=True) def user_info(state): print("state:", state) uinfo = f"""情報: {state["loginuser"]}""" gr.Info(uinfo) #gr.Info("情報: Created by RYH International.") return gr.update(visible=True) def auth(user_name, password): encoded = base64.b64encode(password.encode("utf-8")) # APIエンドポイントのURL url = "https://www.ryhintl.com/dbjson/getjson?sqlcmd=select userid from ku_credential where password = '" + encoded.decode("utf-8") + "'" # GETリクエストの例 response = requests.get(url) if response.status_code == 200: credential_id = response.content.decode('utf-8') parsed_data = json.loads(credential_id) # useridを取得 taken_userid = parsed_data[0]["userid"] if (taken_userid == user_name): state.value["loginuser"] = user_name return True # 認証成功 else: return False def process_invitees(state,input_json): try: # Parse the JSON input invitees = json.loads(input_json) # Generate embeddings using Cohere response = cohere_client.embed( texts=[ 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', '')}" for note in invitees ], model="embed-multilingual-v3.0", input_type="search_document", ) # Upload points to Qdrant client.upload_points( collection_name="knowledge_utility", points=[ models.PointStruct( id=uuid.uuid4().hex, vector=embedding, payload=note, ) for note, embedding in zip(invitees, response.embeddings) ] ) return "Data uploaded successfully!" except Exception as e: return f"Error: {str(e)}" # Function to send Gmail def send_gmail(mail_from, mail_to, mail_subject, mail_body): try: sent_mails = f"From: {mail_from}\nTo: {mail_to}\nSubject: {mail_subject}\nBody:\n{mail_body}\n" except Exception as e: sent_mails = f"Error sending mail: {str(e)}" return sent_mails # Function to handle search query def search(state,query: str): #state["userid"] = "kuuser" global sent_mails # Embed query using Cohere response = cohere_client.embed( texts=[query], model="embed-multilingual-v3.0", input_type="search_query", ) # Query Qdrant collection for relevant points results = client.query_points( collection_name="knowledge_utility", query=response.embeddings[0], limit=1, ).points for result in results: state["score"] = result.score # Filter points based on similarity threshold similarity_threshold = 0.1 # Example threshold for filtering filtered_points = [point for point in results if point.score >= similarity_threshold] #print("filtered_points:",filtered_points) # Apply limit to the filtered points final_limit = len(filtered_points) # Example limit limited_points = filtered_points[:final_limit] #print("finals:",final_limit,limited_points) # Assuming `results` is a list of ScoredPoint objects payload_list = [] # Iterate through the limited results and extract payloads for point in limited_points: # Access the payload attribute and append it to the list #print("point:",point) payload_list.append(point.payload) #print("payload_list:",payload_list) # Template for the invitation letter template = "" # Prepare results in a user-friendly format formatted_results = [ 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']}" for point in results ] #print("formatted_results",formatted_results) final_result = "\n\n".join(formatted_results) res = co.chat( model="command-a-03-2025", messages=[ { "role": "user", "content": final_result+"を要約してください。 必ず、日本語で答えてください。", } ], ) final = res.message.content[0].text # Extract content between "---" start_marker = "---" end_marker = "---" start_index = final.find(start_marker) + len(start_marker) end_index = final.rfind(end_marker) return final,state["score"] # Gradio Blocks Interface with gr.Blocks(css="footer {visibility: hidden;} .custom-image {width: 64px; height: 64px;} .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: state = gr.State({ "userid": "", "loginuser": "", "picture": "", "score": 0 }) gr.LoginButton() # ^ add a login button to the Space m1 = gr.Markdown() m2 = gr.Markdown() ku.load(greeting, inputs=None, outputs=m1) with gr.Column(): gr.HTML('') gr.Markdown("# ナレッジ・エージェント") gr.Markdown("📧 ベクターDBに保存されている知識ベースのインベントリを使用して知識共有します。") with gr.Sidebar(open=False): #gr.Image(value=oauth_profile.picture, elem_classes=["custom-image"]) gr.HTML(""" Knowledge Utility

Knowledge Utility

知識をシェアし、成長を加速させる。

Knowledge Utilityとは?

Knowledge Utilityは、企業や個人が知識を効果的に共有し、成長を促進するためのプラットフォームです。 データ、アイデア、専門知識をシームレスに交換し、新たな価値を生み出します。

主な機能

メリット

Knowledge Utilityを活用することで、効率の向上、意思決定のスピードアップ、そして 組織の成長が期待できます。

""") with gr.Blocks(css=".custom-btn-container { display: flex; justify-content: center; } .custom-btn { width: 150px; height: 30px; background-color: lightblue; border-radius: 10px; font-size: 12px; color: #3C82F6; }") as ubutton: with gr.Row(elem_classes=["custom-btn-container"]): # 中央揃え用のクラス user_btn = gr.Button("情報", elem_classes=["custom-btn"]) user_btn.click(fn=user_info, inputs=[state], outputs=user_btn) #user_btn = gr.Button("情報", elem_classes=["custom-btn"]) #user_btn.click(fn=user_info, inputs=[state], outputs=None) with gr.Tab("KU 検索") as tab_find: with gr.Row(): query_input = gr.Textbox( label="クエリ", placeholder="例)物流・流通業界向けの提案書を内容を教えてください。", info="例)物流・流通業界向けの提案書を内容を教えてください。AI市場の動向を調べています。参考できる事例を教えてください。", value="経営デジタル・トランスフォーメーション関連のプロジェクトの提案書を書こうと思っています。参考できる事例を教えてください。", lines=2, ) with gr.Column(): search_button = gr.Button("実行", elem_classes=["custom-btn"]) clear_button = gr.Button("クリア", elem_classes=["custom-btn"]) result_output = [gr.Textbox(label="結果", show_copy_button=True),gr.Textbox(label="スコア")] # Button click events search_button.click(fn=search, inputs=[state,query_input], outputs=result_output) clear_button.click(lambda: "", None, result_output) with gr.Tab("KU インベントリ登録") as tab_reg: with gr.Row(): input_text = gr.Textbox(label="KU JSON Payroll", lines=10, placeholder="Paste your JSON Payroll here...", info="""[{"kx_subject": "中古車販売における現状と問題点", "kx_creator": "username", "kx_content": "事前情報の収集: 顧客動向、問題・課題の想定、3C分析を通じて仮説を策定する。企業動向、顧客動向、競合動向を分析し、仮説を立案する。仮説提案営業の商談フロー: あいさつ、自社紹介、詳細ヒアリング、仮説検証、解決策の提案、ディスカッション、宿題の出し合い、あいさつのステップを踏む。効果的な商談の進め方: 訪問の趣旨を伝え、基本的な質問をし、相手に話させる。仮説をぶつけ、次回の日付と宿題を決める。ヒアリングの技術: 荷主担当者と営業担当者の知識の差を理解し、必要に応じて役割を分担する。ロジスティクスフローを描き、詳細な設問項目を作成する。", "kx_industry": "物流・流通", "kx_kind": "小売", "kx_category": "提案書", "kx_date": "2025/06/02"}]""") output_text = gr.Textbox(label="Result") with gr.Row(): submit_button = gr.Button("実行", elem_classes=["custom-btn"]) submit_button.click(process_invitees, inputs=[state,input_text], outputs=output_text) # Launch the app ku.load(list_private_models, inputs=None, outputs=[m2, tab_find, tab_reg]) ku.launch(favicon_path="favicon.ico",share=True)