File size: 14,238 Bytes
9e5d4ea
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d8ca5c8
9e5d4ea
 
 
d8ca5c8
 
 
 
d4525cc
9e5d4ea
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
import cohere
import numpy as np
from pgvector.psycopg import register_vector, Bit
import psycopg2
import asyncio
import gradio as gr
from pathlib import Path
from typing import Annotated
from autogen import AssistantAgent, UserProxyAgent
from autogen.coding import LocalCommandLineCodeExecutor
from autogen import ConversableAgent
from autogen import register_function
import mysql.connector
import random
import requests
from groq import Groq
from dotenv import load_dotenv
import os
import json

tool_resp = ""

load_dotenv(verbose=True)

conn = mysql.connector.connect(
        host=os.environ.get("HOST"),
        user=os.environ.get("USER_NAME"),
        password=os.environ.get("PASSWORD"),
        port=os.environ.get("PORT"),
        database=os.environ.get("DB"),
        ssl_disabled=True
    )

cursor = conn.cursor(dictionary=True)

def get_api_keys():
    #token = get_rounrobin()
    token = os.environ["GROQ_API_KEY"]
    return token

# Configure Groq
config_list = [{
    "model": "llama-3.3-70b-versatile",
    "api_key": os.environ["GROQ_API_KEY"],
    "api_type": "groq"
}]

co = cohere.ClientV2(api_key=os.environ["COHERE_API_KEY"])

# Database setup
conn = psycopg2.connect(
    dbname=os.environ.get("DB"),
    user=os.environ.get("USER_NAME"),
    password=os.environ.get("PASSWORD"),
    host=os.environ.get("HOST"),
    port=os.environ.get("PGPORT")
)

cur = conn.cursor()

# Create a directory to store code files from code executor
work_dir = Path("coding")
work_dir.mkdir(exist_ok=True)
code_executor = LocalCommandLineCodeExecutor(work_dir=work_dir)

# Define revenue tool
def get_current_invitee(location):
    """Get the revenue for some material"""
    data = requests.get('https://www.ryhintl.com/dbjson/getjson?sqlcmd=select `id`,`username`,`email`,`division`,`position` from spfx_pinfo')
    # 元のデータ
    data = json.loads(data.content)

    # 指定された形式に変換
    invitee_data = {item["username"]+"様": {"役職": item["position"], "部門": item["division"], "body": "詳細は以下の通りです。・日時:2025年6月1日(土)10時・場所:銀座プレアンタン・内容:新製品の紹介、実演、質疑応答などお忙しい中大変お手数ですが、ぜひ足を運んで頂ければと思っております。承知くださいます様、よろしくお願い申し上げます。"} for item in data}

    script_data = ""
    for item in data:
        script_data += f'''
        {item["username"]}様、
        
        益々ご清祥のこととお喜び申し上げます。
        平素は格別のご厚情を賜り、誠にありがとうございます。

        先日はお忙しい中大変お世話になり、誠にありがとうございます。
        私どもクリーンウォータ株式会社は、浄水器を製造販売する会社であります。
        今回、弊社が新製品の『パーソナル浄水器』を御用達いただき、新商品の発表会を開催することになりました。
        発表会の詳細は以下の通りです。
        ・日時:2025年6月1日(土)10時
        ・場所:銀座プレアンタン
        ・内容:新製品の紹介、実演、質疑応答など
        お忙しい中大変お手数ですが、ぜひ足を運んで頂ければと思っております。
        承知くださいます様、よろしくお願い申し上げます。

        以上、よろしくお願いいたします。
        '''
        print("print:",script_data)

    return script_data

# Create an AI assistant that uses the kpi tool
assistant = AssistantAgent(
#assistant = ConversableAgent(
    name="groq_assistant",
    system_message="""あなたは、次のことができる役に立つAIアシスタントです。
    - 情報検索ツールを使用する
    - 結果を分析して自然言語のみで説明する""",
    llm_config={"config_list": config_list}
)

# Create a user proxy agent that only handles code execution
user_proxy = UserProxyAgent(
#user_proxy = ConversableAgent(
    name="user_proxy",
    human_input_mode="NEVER",
    code_execution_config={"work_dir":"coding", "use_docker":False},
    max_consecutive_auto_reply=2,
    #llm_config={"config_list": config_list}
)

# Register weather tool with the assistant
@user_proxy.register_for_execution()
@assistant.register_for_llm(description="snippetの内容")
def invitee_analysis(
    location: Annotated[str, "title"]
) -> str:
    invitee_details = get_current_invitee(location=location)
    print("after:",invitee_details)

    global tool_resp
    tool_resp = invitee_details
    return invitee_details
    

def get_revenue_and_plot(event1):
    get_api_keys()

    # Start the conversation
    resp = user_proxy.initiate_chat(
        assistant,
        message=f"""3つのことをやってみましょう:
        1. {event1}の内容をtoolを利用して抽出します。
        2. toolを利用して抽出された顧客リストを元に丁重な招待状を作成します。
        3. 拝啓、益々ご清祥のこととお喜び申し上げます。
        平素は格別のご厚情を賜り、誠にありがとうございます。などを使い、日本語で説明してください。
        """
    )
    
    total_tokens = resp.cost['usage_including_cached_inference']['llama-3.3-70b-versatile']['total_tokens']
    
    groq_assistant_contents = [entry['content'] for entry in resp.chat_history if entry['role'] == 'user' and entry['name'] == 'groq_assistant']

    global tool_resp
    print("final:",tool_resp)
    client = Groq(api_key=os.environ["GROQ_API_KEY"])
    system_prompt = {
        "role": "system",
        "content": "You are a helpful assistant, answer questions concisely."
    }

    # Set the user prompt
    #user_input = tool_resp+"を要約してください。顧客リストも含めてください。"
    user_input = tool_resp+"を要約してください。招待状を作るpythonコードを生成してください。生成されるコードに、必ず、顧客リストをcsv形式のテキストで含めてください。"
    user_prompt = {
        "role": "user", "content": user_input
    }

    # Initialize the chat history
    chat_history = [system_prompt, user_prompt]

    response = client.chat.completions.create(
        model="llama-3.3-70b-versatile",
        messages=chat_history,
        max_tokens=4096,
        temperature=0)

    kekka = response.choices[0].message.content

    usages = "使用トークン数: "+str(total_tokens)+ " \n"+kekka

    tmp_resp = groq_assistant_contents[0]

    return tmp_resp,usages

# Embedding function
def embed(input, input_type):
    co = cohere.ClientV2(api_key="GqsxZlKmcBzSultkVOfKPf7kVhYkporXvivq9KHg")
    #response = co.embed(texts=input, model='embed-v4.0', input_type=input_type, embedding_types=['ubinary'])
    response = co.embed(texts=input, model='embed-multilingual-v3.0', input_type=input_type, embedding_types=['ubinary'])
    return [np.unpackbits(np.array(embedding, dtype=np.uint8)) for embedding in response.embeddings.ubinary]

def take_action(state,query):
    resp =  state["prev_comment"]

    if (resp == ""):
        return "営業支援でデータが生成されていません。"
    else:
        system_message = """あなたは、優秀なアシスタントです。"""
    
        message = f'''
        {resp}に基づいて{query}に対する答えを出力してください。金額の桁数は正確にしてください。
        '''

        # Add the system and user messages to the chat history
        messages = [
            {"role": "system", "content": system_message},
            {"role": "user", "content": message},
        ]

        # Step 2: Tool planning and calling
        response = co.chat(
            model="command-r-plus-08-2024",
            messages=messages
        )

        myresp = response.message.content[0].text
        return myresp
    

def ma_action(query):
    
    system_message = """あなたは、優秀なアシスタントです。"""
    
    message = f'''
    {query}に対する答えを出力してください。金額の桁数は正確にしてください。
    '''

    # Add the system and user messages to the chat history
    messages = [
        {"role": "system", "content": system_message},
        {"role": "user", "content": message},
    ]

    # Step 2: Tool planning and calling
    response = co.chat(
        model="command-r-plus-08-2024",
        messages=messages
    )

    myresp = response.message.content[0].text
    return myresp

def search_documents(state,query):
    # Embed the query
    query_embedding = embed([query], 'search_query')[0]

    # Convert numpy array to a Python list or tuple
    query_embedding = query_embedding.tolist()  # Convert to list
    # Alternatively: query_embedding = tuple(query_embedding)

    # Execute SQL query
    cur.execute(
        'SELECT salesID,salesManID,salesManName,CustomerID,CustomerName,Industry,Email,RegistrationDate,OpportunityDetails,OpportunityStage,ExpectedRevenue,ActivityType,ActivityDate,ActivityDetails FROM sales_statusdata ORDER BY datavector <=> %s::vector LIMIT 1',
        (query_embedding,)
    )

    sales_data = ""
    # Fetch results
    data = cur.fetchall()  

    sales_id = data[0][0]
    salesman_id = data[0][1]
    salesman_name = data[0][2]
    customer_id = data[0][3]
    customer_name = data[0][4]
    industry = data[0][5]
    email = data[0][6]
    registration_date = data[0][7]
    opportunity_details = data[0][8]
    opportunity_stage = data[0][9]
    expected_revenue = data[0][10]
    activity_type = data[0][11]
    activity_date = data[0][12]
    activity_details = data[0][13]
    
    sales_data = f"セールズID: {sales_id} 営業担当者ID: {salesman_id} 営業担当者名: {salesman_name} 顧客ID: {customer_id} 顧客名: {customer_name} 業界: {industry} 顧客メール: {email} 登録日: {registration_date} 獲得経緯: {opportunity_details} ステージ: {opportunity_stage} 予想売上: {expected_revenue} タイプ: {activity_type} 営業日付: {activity_date} 詳細: {activity_details}"
    print("sales_data:",sales_data)

    system_message = """あなたは、優秀なアシスタントです。"""

    message = f'''
    {sales_data}に基づいて{query}に対する答えを出力してください。金額の桁数は正確にしてください。
    '''


    # Add the system and user messages to the chat history
    messages = [
        {"role": "system", "content": system_message},
        {"role": "user", "content": message},
    ]

    # Step 2: Tool planning and calling
    response = co.chat(
        model="command-r-plus-08-2024",
        messages=messages
    )

    myresp = response.message.content[0].text
    state["prev_comment"] = myresp
    return myresp



# Setting up Gradio Blocks
with gr.Blocks(css="footer {visibility: hidden;} #custom-btn {width: 150px; height: 30px; padding-left: 0px; margin-left: auto; margin-left: auto; text-align: right; background-color: transparent; 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="営業支援エージェント") as app:
    gr.HTML('<div id="header"><span>🫶 営業支援エージェント</span><img id="logo" src="https://www.ryhintl.com/images/ryhlogo/ryhlogo.png" width="64" height="64" alt="Logo"></div>')
    reload_btn = gr.Button("リーロド",elem_id="custom-btn")
    reload_btn.click(fn=None, inputs=[], outputs=[], js="window.location.reload()")

    state = gr.State({
        "prev_comment": ""
    })

    with gr.Tabs():
        with gr.Tab("営業支援"):
            gr.Markdown("### Sales Support Agent")
            query_input = gr.Textbox(label="Enter your query", value="展示会での直接コンタクトでリードに繋げった案件について説明してください。")
            output = gr.Textbox(label="結果", show_copy_button=True)
            search_button = gr.Button("生成")
            search_button.click(search_documents, inputs=[state,query_input], outputs=output)

        with gr.Tab("アクション"):
            gr.Markdown("### Next Action")
            action_input = gr.Textbox(label="クエリ", value="次の取るべきアクションについて教えてください。")
            action_output = gr.Textbox(label="結果", show_copy_button=True)
            action_button = gr.Button("生成")
            action_button.click(take_action, inputs=[state,action_input], outputs=action_output)

        with gr.Tab("マーケティング・オートメーション (MA)"):
            gr.Markdown("### マーケティング・オートメーション")
            ma_input = gr.Textbox(label="製品発表会ご招待する顧客メール発送", value="新製品(パーソナル浄水器)の製品発表会を2025/6/1 10:00に銀座プレアンタンで開催しようとしています。DBから招待顧客のリストを取り出し、Invitation Letterを作成してください。")
            ma_output = gr.Textbox(label="結果", show_copy_button=True)
            ma_usage = gr.Textbox(label="Usage", show_copy_button=True)
            ma_button = gr.Button("生成")
            ma_button.click(get_revenue_and_plot, inputs=[ma_input], outputs=[ma_output,ma_usage])

        with gr.Tab("マーケティング・フレージング (MP)"):
            gr.Markdown("### マーケティング・フレージング")
            mp_input = gr.Textbox(label="見込み客に発送するSNSとメールの本文", value="見込み顧客を育成するために、メールやSNSを自動配信しようと思っています。見込み客に発送するSNSとメールの本文を作ってください。")
            mp_output = gr.Textbox(label="結果", show_copy_button=True)
            mp_button = gr.Button("生成")
            mp_button.click(ma_action, inputs=[mp_input], outputs=mp_output)

# Launch the interface
app.launch(favicon_path="favicon.ico")