This commit is contained in:
narawat lamaiin
2024-08-25 11:50:50 +07:00
parent 2e90665fb6
commit 232202d1ca
4 changed files with 149 additions and 21 deletions

View File

@@ -1,5 +1,5 @@
using Revise # remove when this package is completed
using YiemAgent, GeneralUtils, JSON3, MQTTClient, Dates, UUIDs, LibPQ
using YiemAgent, GeneralUtils, JSON3, MQTTClient, Dates, UUIDs, LibPQ, Base64, DataFrames
using Base.Threads
# ---------------------------------------------- 100 --------------------------------------------- #
@@ -55,20 +55,127 @@ function text2textInstructLLM(prompt::String)
return response
end
# Instantiate an agent
a = YiemAgent.sommelier(
text2textInstructLLM,
executeSQL;
name="assistant",
id="testingSessionID", # agent instance id
function executeSQLVectorDB(sql)
DBconnection = LibPQ.Connection("host=192.168.88.12 port=5433 dbname=SQLVectorDB user=yiemtechnologies@gmail.com password=yiem@Postgres_0.0")
result = LibPQ.execute(DBconnection, sql)
close(DBconnection)
return result
end
function addSQLVectorDB(state)
# get embedding of the query
query = [state[:thoughtHistory][:question]]
msgMeta = GeneralUtils.generate_msgMeta(
config[:externalservice][:text2textinstruct][:mqtttopic];
msgPurpose= "embedding",
senderName= "yiemagent",
senderId= string(uuid4()),
receiverName= "text2textinstruct",
mqttBrokerAddress= config[:mqttServerInfo][:broker],
mqttBrokerPort= config[:mqttServerInfo][:port],
)
outgoingMsg = Dict(
:msgMeta=> msgMeta,
:payload=> Dict(
:text=> query
)
)
response = GeneralUtils.sendReceiveMqttMsg(outgoingMsg)
embedding = response[:response][:embeddings][1]
# check whether there is close enough vector already store in vectorDB. if no, add, else skip
sql =
"""
SELECT *, embedding <-> '$embedding' as distance
FROM sql_statement_repository
ORDER BY distance LIMIT 1;
"""
response = executeSQLVectorDB(sql)
df = DataFrame(response)
row, col = size(df)
distance = row == 0 ? Inf : df[1, :distance]
if row == 0 || distance > 10 # no close enough SQL stored in the database
latestKey, _ = GeneralUtils.findHighestIndexKey(state[:thoughtHistory], :action_input)
_sqlStatement = state[:thoughtHistory][latestKey]
if occursin("SELECT", _sqlStatement) # make sure it is an SQL statement before adding into DB
sqlStatementBase64 = base64encode(_sqlStatement)
sqlStatement = replace(_sqlStatement, "'"=>"")
sql =
"""
INSERT INTO sql_statement_repository (question, sql_statement, sql_statement_base64, embedding) VALUES ('$query', '$sqlStatement', '$sqlStatementBase64', '$embedding');
"""
_ = executeSQLVectorDB(sql)
println("--> added new SQL statement to vectorDB ", @__FILE__, " ", @__LINE__)
println(sqlStatement)
end
end
end
function querySQLVectorDB(state)
# provide similarSQL at the first time thinking only
latestKey, _ = GeneralUtils.findHighestIndexKey(state[:thoughtHistory], :action_input)
if latestKey === nothing
# get embedding of the query
query = [state[:thoughtHistory][:question]]
msgMeta = GeneralUtils.generate_msgMeta(
config[:externalservice][:text2textinstruct][:mqtttopic];
msgPurpose= "embedding",
senderName= "yiemagent",
senderId= string(uuid4()),
receiverName= "text2textinstruct",
mqttBrokerAddress= config[:mqttServerInfo][:broker],
mqttBrokerPort= config[:mqttServerInfo][:port],
)
outgoingMsg = Dict(
:msgMeta=> msgMeta,
:payload=> Dict(
:text=> query
)
)
response = GeneralUtils.sendReceiveMqttMsg(outgoingMsg)
embedding = response[:response][:embeddings][1]
# check whether there is close enough vector already store in vectorDB. if no, add, else skip
sql =
"""
SELECT *, embedding <-> '$embedding' as distance
FROM sql_statement_repository
ORDER BY distance LIMIT 1;
"""
response = executeSQLVectorDB(sql)
df = DataFrame(response)
row, col = size(df)
distance = row == 0 ? Inf : df[1, :distance]
if row != 0 && distance < 100
# if there is usable SQL, return it.
sqlStatementBase64 = df[1, :sql_statement_base64]
sqlStatement = String(base64decode(sqlStatementBase64))
println("--> getting SQL statement from vectorDB ", @__FILE__, " ", @__LINE__)
println(sqlStatement)
return sqlStatement
else
return nothing
end
end
return nothing
end
# Instantiate an agent
a = YiemAgent.sommelier(
text2textInstructLLM,
executeSQL,
querySQLVectorDB,
addSQLVectorDB;
name= "Janie",
id= sessionId, # agent instance id
)
function main()
userinput = "Hello, I would like a get a bottle of wine."
for i in 1:10
response = YiemAgent.conversation(a, Dict(:text=> userinput))
println("")
println("--> assistant response: \n", response)
userinput = ""
for i in 1:3
if userinput == ""
@@ -79,6 +186,9 @@ function main()
break
end
end
response = YiemAgent.conversation(a, Dict(:text=> userinput))
println("")
println("--> assistant response: \n", response)
end
end
@@ -87,8 +197,13 @@ main()
"""
I'm joining a graduation party this evening. I want a bottle of dry white wine from the US. I'm ok with any price range.
Well, the party is small casual with close friends and no food serving.
I'm open to suggestion since I have no specific idea about wine.
I'm open to suggestion since I have no specific idea.
I'm ok with any region.
The input is instructions on how you want the presentation to be conducted.
"""