This commit is contained in:
narawat lamaiin
2024-08-17 22:32:16 +07:00
parent e1592f9d8e
commit 9d805fb3e7
3 changed files with 198 additions and 43 deletions

View File

@@ -1283,7 +1283,7 @@ function generatechat(memory::Dict, chathistory::Vector, text2textInstructLLM::F
Your goal is: Recommend the best wines from your inventory that align with the user's preferences. Your goal is: Recommend the best wines from your inventory that align with the user's preferences.
Your responsibility includes: Your responsibility includes:
1) Convey your thoughts to the user 1) Given the situation, convey your thoughts to the user
At each round of conversation, you will be given the current situation: At each round of conversation, you will be given the current situation:
Your conversation with the user: ... Your conversation with the user: ...
@@ -1297,7 +1297,7 @@ function generatechat(memory::Dict, chathistory::Vector, text2textInstructLLM::F
- Focus on the latest conversation. - Focus on the latest conversation.
You should then respond to the user with: You should then respond to the user with:
1) chat: Given the current situation, what will you say to the user? 1) chat: Given the situation, convey your thoughts to the user
2) mentioning_wine: Are you mentioning specific wine name to the user? Can be "Yes" or "No" 2) mentioning_wine: Are you mentioning specific wine name to the user? Can be "Yes" or "No"
You should only respond in format as described below: You should only respond in format as described below:
@@ -1398,13 +1398,58 @@ end
function generatequestion(a, text2textInstructLLM::Function)::String function generatequestion(a, text2textInstructLLM::Function)::String
# systemmsg =
# """
# You are a helpful assistant acting as a polite, website-based sommelier for an online wine store.
# Your goal is: Help the user select the best wines from your inventory that align with the user's preferences.
# Your responsibility includes:
# 1) Self questioning about the current situation
# 2) Thanks the user when they are done choosing wines and invite them to comeback next time
# Your responsibility does not include:
# 1) Processing sales orders or engaging in any other sales-related activities.
# At each round of conversation, you will be given the current situation:
# Your conversation with the user: ...
# Context: ...
# You must follow the following guidelines:
# - Your question should be specific, self-contained and not require any additional context.
# - Do not generate any question or comments at the end.
# - Once the user has selected their wine, ask the user if they need any further assistance. Do not offer any additional services. If the user doesn't need any further assistance, say goodbye and invite them to come back next time.
# You should follow the following guidelines:
# - Focus on the latest conversation.
# - Do not ask the user about wine's flavor e.g. floral, citrusy, nutty or some thing similar as these terms cannot be used to search the database.
# - All wines in your inventory are always in stock.
# You should then respond to the user with:
# 1) Reasoning: State your detailed reasoning of the current situation
# 2) Q: Based on the current situation, ask yourself at least two, but no more than five, questions about what you need to do to achieve the goal.
# 3) A: Based on the current situation, answer to yourself the best you can
# You must only respond in format as described below:
# Reasoning: ...
# Q 1: ...
# A 1: ...
# Q 2: ...
# A 2: ...
# Q 3: ...
# A 3: ...
# ...
# Let's begin!
# """
systemmsg = systemmsg =
""" """
You are a helpful assistant acting as a polite, website-based sommelier for an online wine store. You are a helpful assistant acting as a polite, website-based sommelier for an online wine store.
Your goal is: Help the user select the best wines from your inventory that align with the user's preferences. Your goal includes:
1) Help the user select the best wines from your inventory that align with the user's preferences.
Your responsibility includes: Your responsibility includes:
1) Self questioning about the current situation 1) Ask yourself what to do about the current situation
2) Thanks the user when they are done choosing wines and invite them to comeback next time 2) Thanks the user when they are done choosing wines and invite them to comeback next time
Your responsibility does not include: Your responsibility does not include:
@@ -1426,8 +1471,16 @@ function generatequestion(a, text2textInstructLLM::Function)::String
You should then respond to the user with: You should then respond to the user with:
1) Reasoning: State your detailed reasoning of the current situation 1) Reasoning: State your detailed reasoning of the current situation
2) Q: Based on the current situation, ask yourself at least two, but no more than five, questions about what you need to do to achieve the goal. 2) Q: Given the situation, "ask yourself" about the situation at least two, but no more than five, questions.
3) A: Based on the current situation, answer to yourself the best you can 3) A: Given the situation, "answer to yourself" the best you can
Here are some examples:
Q: The user is asking for a cappuccino. Do I have it at my cafe?
A: No I don't.
Q: Since I don't have a cappuccino but I have a Late, should I ask if they are okay with that?
A: Yes, I should.
Q: Are they allergic to milk?
A: Since they mentioned a cappuccino before, I think they are not allergic to milk.
You must only respond in format as described below: You must only respond in format as described below:
Reasoning: ... Reasoning: ...
@@ -1497,7 +1550,6 @@ function generatequestion(a, text2textInstructLLM::Function)::String
error("generatequestion failed to generate a thought ", response) error("generatequestion failed to generate a thought ", response)
end end
function generateSituationReport(a, text2textInstructLLM::Function)::Dict function generateSituationReport(a, text2textInstructLLM::Function)::Dict
# systemmsg = # systemmsg =
@@ -1523,23 +1575,24 @@ function generateSituationReport(a, text2textInstructLLM::Function)::Dict
systemmsg = systemmsg =
""" """
You are the assistant being in the given events. You are the assistant being in the given events.
Your task is to writes a summary of each event. Your task is to writes a summary for each event.
At each round of conversation, you will be given the situation: At each round of conversation, you will be given the situation:
Total events: number of events you need to summarize.
Events timeline: ... Events timeline: ...
Context: ... Context: ...
You should then respond to the user with: You should then respond to the user with:
event: a detailed summary of each event without exaggerated details. event: a detailed summary for each event without exaggerated details.
You must only respond in format as described below: You must only respond in format as described below:
event 1: ... event_1: ...
event 2: ... event_2: ...
... ...
Here are some examples: Here are some examples:
event 1: The user ask me about where to buy a toy. event_1: The user ask me about where to buy a toy.
event 2: I told the user to go to the store at 2nd floor. event_2: I told the user to go to the store at 2nd floor.
Let's begin! Let's begin!
""" """
@@ -1559,6 +1612,7 @@ function generateSituationReport(a, text2textInstructLLM::Function)::Dict
for attempt in 1:10 for attempt in 1:10
usermsg = usermsg =
""" """
Total events: $(length(a.memory[:events]))
Events timeline: $timeline Events timeline: $timeline
$errornote $errornote
""" """
@@ -1576,7 +1630,6 @@ function generateSituationReport(a, text2textInstructLLM::Function)::Dict
<|start_header_id|>assistant<|end_header_id|> <|start_header_id|>assistant<|end_header_id|>
""" """
try
response = text2textInstructLLM(prompt) response = text2textInstructLLM(prompt)
# responsedict = GeneralUtils.textToDict(response, # responsedict = GeneralUtils.textToDict(response,
# ["summary", "presented", "selected"], # ["summary", "presented", "selected"],
@@ -1584,19 +1637,122 @@ function generateSituationReport(a, text2textInstructLLM::Function)::Dict
# println("--> generateSituationReport ", @__FILE__, " ", @__LINE__) # println("--> generateSituationReport ", @__FILE__, " ", @__LINE__)
pprintln(response) pprintln(response)
eventcount = count("event_", response)
if eventcount < length(a.memory[:events])
errornote = "Note: You need to summarize every events."
println("the summary covers $eventcount/$(length(a.memory[:events])) ", @__FILE__, " ", @__LINE__)
else
return Dict(:recap=> response) return Dict(:recap=> response)
catch e
io = IOBuffer()
showerror(io, e)
errorMsg = String(take!(io))
st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
println("")
println("Attempt $attempt. Error occurred: $errorMsg\n$st")
println("")
end end
end end
error("generateSituationReport failed to generate a thought ", response) error("generateSituationReport failed to generate a thought ", response)
end end
# function generateSituationReport(a, text2textInstructLLM::Function)::Dict
# # systemmsg =
# # """
# # You are a helpful assistant in the given timeline.
# # You task is to writes a situational report on the current situation.
# # At each round of conversation, you will be given the current situation:
# # Timeline: ...
# # Context: ...
# # You should then respond to the user with:
# # 1) report: State your detailed situational report on the current situation.
# # 2) wine_selected: Indicates whether the user selected wine. It can be the name of the selected wine or "None"
# # You must only respond in format as described below:
# # report: ...
# # wine_selected: ...
# # Let's begin!
# # """
# systemmsg =
# """
# You are the assistant being in the given events.
# Your task is to writes a summary of each event.
# At each round of conversation, you will be given the situation:
# Events timeline: ...
# Context: ...
# You should then respond to the user with:
# event: a detailed summary of each event without exaggerated details.
# You must only respond in format as described below:
# event 1: ...
# event 2: ...
# ...
# Here are some examples:
# event 1: The user ask me about where to buy a toy.
# event 2: I told the user to go to the store at 2nd floor.
# Let's begin!
# """
# timeline = ""
# for (i, event) in enumerate(a.memory[:events])
# if event[:outcome] === nothing
# timeline *= "$i) $(event[:subject])> $(event[:action_or_dialogue])\n"
# else
# timeline *= "$i) $(event[:subject])> $(event[:action_or_dialogue]) $(event[:outcome])\n"
# end
# end
# errornote = ""
# response = nothing # store for show when error msg show up
# for attempt in 1:10
# usermsg =
# """
# Events timeline: $timeline
# $errornote
# """
# _prompt =
# [
# Dict(:name=> "system", :text=> systemmsg),
# Dict(:name=> "user", :text=> usermsg)
# ]
# # put in model format
# prompt = GeneralUtils.formatLLMtext(_prompt, "llama3instruct")
# prompt *=
# """
# <|start_header_id|>assistant<|end_header_id|>
# """
# try
# response = text2textInstructLLM(prompt)
# # responsedict = GeneralUtils.textToDict(response,
# # ["summary", "presented", "selected"],
# # rightmarker=":", symbolkey=true)
# # println("--> generateSituationReport ", @__FILE__, " ", @__LINE__)
# pprintln(response)
# eventcount = count("event", response)
# if eventcount < length(a.memory[:events])
# error("the summary is missing some events ", @__FILE__, " ", @__LINE__)
# end
# return Dict(:recap=>response)
# catch e
# io = IOBuffer()
# showerror(io, e)
# errorMsg = String(take!(io))
# st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
# println("")
# println("Attempt $attempt. Error occurred: $errorMsg\n$st")
# println("")
# end
# end
# error("generateSituationReport failed to generate a thought ", response)
# end

View File

@@ -445,6 +445,16 @@ function extractWineAttributes_1(a::T1, input::T2)::String where {T1<:agent, T2<
end end
end end
# check if region is mentioned in the input
if !occursin("NA", responsedict[:region]) && !occursin(responsedict[:region], input)
if attempt < maxattempt
errornote = "You are halucinating, $(responsedict[:region]) is not mentioned in the input"
error("$(responsedict[:region]) is not mentioned in the input")
else
responsedict[:region] = "NA"
end
end
responsedict[:flavors] = replace(responsedict[:flavors], "notes"=>"") responsedict[:flavors] = replace(responsedict[:flavors], "notes"=>"")
delete!(responsedict, :reasoning) delete!(responsedict, :reasoning)
delete!(responsedict, :tasting_notes) delete!(responsedict, :tasting_notes)

View File

@@ -19,14 +19,6 @@ msgMeta = GeneralUtils.generate_msgMeta(
replyTopic = config[:servicetopic][:mqtttopic] # ask frontend reply to this instance_chat_topic replyTopic = config[:servicetopic][:mqtttopic] # ask frontend reply to this instance_chat_topic
) )
# commConfig = Dict(
# :mqttServerInfo=> config[:mqttServerInfo],
# :receivemsg=> Dict(
# :prompt=> config[:servicetopic][:mqtttopic], # topic to receive prompt i.e. frontend send msg to this topic
# ),
# :externalservice=> config[:externalservice],
# )
function executeSQL(sql::T) where {T<:AbstractString} function executeSQL(sql::T) where {T<:AbstractString}
DBconnection = LibPQ.Connection("host=192.168.88.12 port=5432 dbname=yiem_wine_assistant user=yiem password=yiem@Postgres_0.0") DBconnection = LibPQ.Connection("host=192.168.88.12 port=5432 dbname=yiem_wine_assistant user=yiem password=yiem@Postgres_0.0")
result = LibPQ.execute(DBconnection, sql) result = LibPQ.execute(DBconnection, sql)
@@ -56,15 +48,12 @@ function text2textInstructLLM(prompt::String)
) )
) )
_response = GeneralUtils.sendReceiveMqttMsg(outgoingMsg) _response = GeneralUtils.sendReceiveMqttMsg(outgoingMsg; timeout=120)
response = _response[:response][:text] response = _response[:response][:text]
return response return response
end end
# Instantiate an agent # Instantiate an agent
a = YiemAgent.sommelier( a = YiemAgent.sommelier(
text2textInstructLLM, text2textInstructLLM,
@@ -88,7 +77,7 @@ end
main() main()
""" """
I'm joining a graduation party this evening. I have unlimited budget and I'm ok with wines in all price range. I want a bottle of full bodied, dry white wine from the U.S. I'm joining a graduation party this evening. I want a bottle of full bodied, dry white wine from the U.S. and I'm ok with all price range.
Well, the party is small casual with close friends and no food serving. 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 about wine.