This commit is contained in:
narawat lamaiin
2024-10-15 07:55:03 +07:00
parent aaaadc7377
commit 523a8a7b41

View File

@@ -96,7 +96,7 @@ julia> output_thoughtDict = Dict(
# Signature # Signature
""" """
function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol, Any} where {T<:agent} function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol,Any} where {T<:agent}
# lessonDict = copy(JSON3.read("lesson.json")) # lessonDict = copy(JSON3.read("lesson.json"))
@@ -258,6 +258,10 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol, Any} where {T<:age
You should follow the following guidelines: You should follow the following guidelines:
- Identifying at least four preferences before checking inventory significantly improves search results - Identifying at least four preferences before checking inventory significantly improves search results
- Sometimes, the item a user desires might not be available in your inventory. In such cases, inform the user that the item is unavailable and suggest an alternative instead.
For your information:
- vintage 0 means non-vintage.
You should then respond to the user with interleaving Understanding, Reasoning, Plan, Action: You should then respond to the user with interleaving Understanding, Reasoning, Plan, Action:
1) Understanding: 1) Understanding:
@@ -269,7 +273,7 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol, Any} where {T<:age
- CHATBOX which you can use to talk with the user. The input is your intentions for the dialogue. Be specific. - CHATBOX which you can use to talk with the user. The input is your intentions for the dialogue. Be specific.
- CHECKINVENTORY which you can use to check info about wine in your inventory. The input is a search term in verbal English. - CHECKINVENTORY which you can use to check info about wine in your inventory. The input is a search term in verbal English.
Good query example: black car, a stereo, 200 mile range, electric motor. Good query example: black car, a stereo, 200 mile range, electric motor.
- PRESENTBOX which you can use to introduce / suggest / recommend wines you just found in the database to the user. - PRESENTBOX which you can use to introduce / suggest / recommend wine label you just found in the inventory to the user. Not for general conversation nor follow up conversation.
The input is instructions on how you want the presentation to be conducted. The input is instructions on how you want the presentation to be conducted.
Here are some input examples, Here are some input examples,
"First, provide detailed introductions of Zena Crown, Schrader Cabernet Sauvignon. "First, provide detailed introductions of Zena Crown, Schrader Cabernet Sauvignon.
@@ -277,7 +281,7 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol, Any} where {T<:age
Third, explain the potential impact each option could bring to the user." Third, explain the potential impact each option could bring to the user."
- ENDCONVERSATION which you can use when you want to finish the conversation with the user. The input is "NA". - ENDCONVERSATION which you can use when you want to finish the conversation with the user. The input is "NA".
4) Action_input: input of the action 4) Action_input: input of the action
5) Mentioning_wine: Are you mentioning specific wine name to the user? Can be "Yes" or "No" 5) Mentioning_wine: Are you mentioning specific wine label or winery 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:
Understanding: ... Understanding: ...
@@ -293,7 +297,7 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol, Any} where {T<:age
totalevents = length(a.memory[:events]) totalevents = length(a.memory[:events])
ind = ind =
if totalevents > recent if totalevents > recent
start = totalevents-recent start = totalevents - recent
start:totalevents start:totalevents
else else
1:totalevents 1:totalevents
@@ -317,8 +321,7 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol, Any} where {T<:age
response = nothing # placeholder for show when error msg show up response = nothing # placeholder for show when error msg show up
for attempt in 1:10 for attempt in 1:10
usermsg = usermsg = """
"""
Recap: $(a.memory[:recap]) Recap: $(a.memory[:recap])
Your recent events: $timeline Your recent events: $timeline
Your Q&A: $(a.memory[:QandA]) Your Q&A: $(a.memory[:QandA])
@@ -327,14 +330,13 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol, Any} where {T<:age
_prompt = _prompt =
[ [
Dict(:name=> "system", :text=> systemmsg), Dict(:name => "system", :text => systemmsg),
Dict(:name=> "user", :text=> usermsg) Dict(:name => "user", :text => usermsg)
] ]
# put in model format # put in model format
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct") prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct")
prompt *= prompt *= """
"""
<|start_header_id|>assistant<|end_header_id|> <|start_header_id|>assistant<|end_header_id|>
""" """
@@ -372,12 +374,12 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol, Any} where {T<:age
responsedict[:action_name] != "CHECKINVENTORY" responsedict[:action_name] != "CHECKINVENTORY"
errornote = "Note: You can't recommend wines yet. You must check your inventory before recommending wine to the user." errornote = "Note: You can't recommend wines yet. You must check your inventory before recommending wine to the user."
error( "You can't recommend wines yet. You must check your inventory before recommending wines") error("You can't recommend wines yet. You must check your inventory before recommending wines")
elseif responsedict[:action_name] == "PRESENTBOX" && isMemEmpty && elseif responsedict[:action_name] == "PRESENTBOX" && isMemEmpty &&
responsedict[:action_name] != "CHECKINVENTORY" responsedict[:action_name] != "CHECKINVENTORY"
errornote = "Note: You can't recommend wines yet. You must check your inventory before recommending wine to the user." errornote = "Note: You can't recommend wines yet. You must check your inventory before recommending wine to the user."
error( "You can't recommend wines yet. You must check your inventory before recommending wines") error("You can't recommend wines yet. You must check your inventory before recommending wines")
else else
errornote = "" errornote = ""
end end
@@ -419,10 +421,9 @@ julia>
# Signature # Signature
""" """
function evaluator(config::T1, state::T2 function evaluator(config::T1, state::T2
)::Tuple{String, Integer} where {T1<:AbstractDict, T2<:AbstractDict} )::Tuple{String,Integer} where {T1<:AbstractDict,T2<:AbstractDict}
systemmsg = systemmsg = """
"""
Analyze the trajectories of a solution to a question answering task. The trajectories are Analyze the trajectories of a solution to a question answering task. The trajectories are
labeled by environmental observations about the situation, thoughts that can reason about labeled by environmental observations about the situation, thoughts that can reason about
the current situation and actions that can be three types: the current situation and actions that can be three types:
@@ -475,21 +476,19 @@ function evaluator(config::T1, state::T2
Let's begin! Let's begin!
""" """
usermsg = usermsg = """
"""
$(JSON3.write(state[:thoughtHistory])) $(JSON3.write(state[:thoughtHistory]))
""" """
chathistory = chathistory =
[ [
Dict(:name=> "system", :text=> systemmsg), Dict(:name => "system", :text => systemmsg),
Dict(:name=> "user", :text=> usermsg) Dict(:name => "user", :text => usermsg)
] ]
# put in model format # put in model format
prompt = formatLLMtext(chathistory, "llama3instruct") prompt = formatLLMtext(chathistory, "llama3instruct")
prompt *= prompt *= """
"""
<|start_header_id|>assistant<|end_header_id|> <|start_header_id|>assistant<|end_header_id|>
{ {
""" """
@@ -503,20 +502,20 @@ function evaluator(config::T1, state::T2
msgMeta = GeneralUtils.generate_msgMeta( msgMeta = GeneralUtils.generate_msgMeta(
externalService[:mqtttopic], externalService[:mqtttopic],
senderName= "evaluator", senderName="evaluator",
senderId= string(uuid4()), senderId=string(uuid4()),
receiverName= "text2textinstruct", receiverName="text2textinstruct",
mqttBroker= config[:mqttServerInfo][:broker], mqttBroker=config[:mqttServerInfo][:broker],
mqttBrokerPort= config[:mqttServerInfo][:port], mqttBrokerPort=config[:mqttServerInfo][:port],
) )
outgoingMsg = Dict( outgoingMsg = Dict(
:msgMeta=> msgMeta, :msgMeta => msgMeta,
:payload=> Dict( :payload => Dict(
:text=> prompt, :text => prompt,
:kwargs=> Dict( :kwargs => Dict(
:max_tokens=> 512, :max_tokens => 512,
:stop=> ["<|eot_id|>"], :stop => ["<|eot_id|>"],
) )
) )
) )
@@ -525,8 +524,7 @@ function evaluator(config::T1, state::T2
try try
response = GeneralUtils.sendReceiveMqttMsg(outgoingMsg) response = GeneralUtils.sendReceiveMqttMsg(outgoingMsg)
_responseJsonStr = response[:response][:text] _responseJsonStr = response[:response][:text]
expectedJsonExample = expectedJsonExample = """
"""
Here is an expected JSON format: Here is an expected JSON format:
{"evaluation": "...", "score": "..."} {"evaluation": "...", "score": "..."}
""" """
@@ -568,11 +566,10 @@ julia>
# Signature # Signature
""" """
function reflector(config::T1, state::T2)::String where {T1<:AbstractDict, T2<:AbstractDict} function reflector(config::T1, state::T2)::String where {T1<:AbstractDict,T2<:AbstractDict}
# https://github.com/andyz245/LanguageAgentTreeSearch/blob/main/hotpot/hotpot.py # https://github.com/andyz245/LanguageAgentTreeSearch/blob/main/hotpot/hotpot.py
_prompt = _prompt = """
"""
You are a helpful sommelier working for a wine store. You are a helpful sommelier working for a wine store.
Your goal is to recommend the best wine from your inventory that match the user preferences. Your goal is to recommend the best wine from your inventory that match the user preferences.
You will be given a question and a trajectory of the previous help you've done for a user. You will be given a question and a trajectory of the previous help you've done for a user.
@@ -635,20 +632,20 @@ function reflector(config::T1, state::T2)::String where {T1<:AbstractDict, T2<:A
msgMeta = GeneralUtils.generate_msgMeta( msgMeta = GeneralUtils.generate_msgMeta(
a.config[:externalservice][:text2textinstruct][:mqtttopic], a.config[:externalservice][:text2textinstruct][:mqtttopic],
senderName= "reflector", senderName="reflector",
senderId= string(uuid4()), senderId=string(uuid4()),
receiverName= "text2textinstruct", receiverName="text2textinstruct",
mqttBroker= config[:mqttServerInfo][:broker], mqttBroker=config[:mqttServerInfo][:broker],
mqttBrokerPort= config[:mqttServerInfo][:port], mqttBrokerPort=config[:mqttServerInfo][:port],
) )
outgoingMsg = Dict( outgoingMsg = Dict(
:msgMeta=> msgMeta, :msgMeta => msgMeta,
:payload=> Dict( :payload => Dict(
:text=> prompt, :text => prompt,
:kwargs=> Dict( :kwargs => Dict(
:max_tokens=> 512, :max_tokens => 512,
:stop=> ["<|eot_id|>"], :stop => ["<|eot_id|>"],
) )
) )
) )
@@ -657,8 +654,7 @@ function reflector(config::T1, state::T2)::String where {T1<:AbstractDict, T2<:A
try try
response = GeneralUtils.sendReceiveMqttMsg(outgoingMsg) response = GeneralUtils.sendReceiveMqttMsg(outgoingMsg)
_responseJsonStr = response[:response][:text] _responseJsonStr = response[:response][:text]
expectedJsonExample = expectedJsonExample = """
"""
Here is an expected JSON format: Here is an expected JSON format:
{"reflection": "..."} {"reflection": "..."}
""" """
@@ -883,10 +879,10 @@ function conversation(a::sommelier, userinput::Dict)
# add user activity to events memory # add user activity to events memory
push!(a.memory[:events], push!(a.memory[:events],
eventdict(; eventdict(;
event_description= "the user talks to the assistant.", event_description="the user talks to the assistant.",
timestamp= Dates.now(), timestamp=Dates.now(),
subject= "user", subject="user",
action_or_dialogue= userinput[:text], action_or_dialogue=userinput[:text],
) )
) )
@@ -905,10 +901,10 @@ function conversation(a::sommelier, userinput::Dict)
push!(a.memory[:events], push!(a.memory[:events],
eventdict(; eventdict(;
event_description= "the assistant talks to the user.", event_description="the assistant talks to the user.",
timestamp= Dates.now(), timestamp=Dates.now(),
subject= "assistant", subject="assistant",
action_or_dialogue= chatresponse, action_or_dialogue=chatresponse,
) )
) )
return chatresponse return chatresponse
@@ -928,10 +924,10 @@ function conversation(a::companion, userinput::Dict)
# add user activity to events memory # add user activity to events memory
push!(a.memory[:events], push!(a.memory[:events],
eventdict(; eventdict(;
event_description= "the user talks to the assistant.", event_description="the user talks to the assistant.",
timestamp= Dates.now(), timestamp=Dates.now(),
subject= "user", subject="user",
action_or_dialogue= userinput[:text], action_or_dialogue=userinput[:text],
) )
) )
chatresponse = generatechat(a) chatresponse = generatechat(a)
@@ -940,10 +936,10 @@ function conversation(a::companion, userinput::Dict)
push!(a.memory[:events], push!(a.memory[:events],
eventdict(; eventdict(;
event_description= "the assistant talks to the user.", event_description="the assistant talks to the user.",
timestamp= Dates.now(), timestamp=Dates.now(),
subject= "assistant", subject="assistant",
action_or_dialogue= chatresponse, action_or_dialogue=chatresponse,
) )
) )
return chatresponse return chatresponse
@@ -966,7 +962,7 @@ julia>
# Signature # Signature
""" """
function think(a::T)::NamedTuple{(:actionname, :result), Tuple{String, String}} where {T<:agent} function think(a::T)::NamedTuple{(:actionname, :result),Tuple{String,String}} where {T<:agent}
a.memory[:recap] = generateSituationReport(a, a.text2textInstructLLM; skiprecent=5) a.memory[:recap] = generateSituationReport(a, a.text2textInstructLLM; skiprecent=5)
a.memory[:QandA] = generatequestion(a, a.text2textInstructLLM; recent=5) a.memory[:QandA] = generatequestion(a, a.text2textInstructLLM; recent=5)
@@ -1006,14 +1002,14 @@ function think(a::T)::NamedTuple{(:actionname, :result), Tuple{String, String}}
select = haskey(response, :select) ? response[:select] : nothing select = haskey(response, :select) ? response[:select] : nothing
reward::Integer = haskey(response, :reward) ? response[:reward] : 0 reward::Integer = haskey(response, :reward) ? response[:reward] : 0
isterminal::Bool = haskey(response, :isterminal) ? response[:isterminal] : false isterminal::Bool = haskey(response, :isterminal) ? response[:isterminal] : false
errormsg::Union{AbstractString, Nothing} = haskey(response, :errormsg) ? response[:errormsg] : nothing errormsg::Union{AbstractString,Nothing} = haskey(response, :errormsg) ? response[:errormsg] : nothing
success::Bool = haskey(response, :success) ? response[:success] : false success::Bool = haskey(response, :success) ? response[:success] : false
# manage memory (pass msg to generatechat) # manage memory (pass msg to generatechat)
if actionname == "CHATBOX" if actionname == "CHATBOX"
a.memory[:CHATBOX] = result a.memory[:CHATBOX] = result
elseif actionname == "CHECKINVENTORY" elseif actionname == "CHECKINVENTORY"
push!(a.memory[:shortmem], Dict(Symbol(actionname)=> result)) push!(a.memory[:shortmem], Dict(Symbol(actionname) => result))
elseif actionname == "PRESENTBOX" # tell the generatechat() elseif actionname == "PRESENTBOX" # tell the generatechat()
a.memory[:CHATBOX] = result a.memory[:CHATBOX] = result
elseif actionname == "ENDCONVERSATION" elseif actionname == "ENDCONVERSATION"
@@ -1048,8 +1044,7 @@ julia>
# Signature # Signature
""" """
function generatechat(a::sommelier) function generatechat(a::sommelier)
systemmsg = systemmsg = """
"""
Your name is $(a.name). You are a helpful assistant acting as a polite, website-based sommelier for an online wine store. Your name is $(a.name). You are a helpful assistant acting as a polite, website-based sommelier for an online wine store.
You are currently talking with the user. You are currently talking with the user.
Your goal includes: Your goal includes:
@@ -1075,7 +1070,7 @@ function generatechat(a::sommelier)
- If the user interrupts, prioritize the user - If the user interrupts, prioritize the user
You should then respond to the user with: You should then respond to the user with:
1) Mentioning_wine: Are you going to mentioning specific wine name to the user? Can be "Yes" or "No" 1) Mentioning_wine: Are you going to mentioning specific wine label or winery to the user? Can be "Yes" or "No"
2) Chat: Given the situation, what would you say to the user? 2) Chat: Given the situation, what would you say to the user?
You should only respond in format as described below: You should only respond in format as described below:
@@ -1097,8 +1092,7 @@ function generatechat(a::sommelier)
response = nothing # placeholder for show when error msg show up response = nothing # placeholder for show when error msg show up
for attempt in 1:10 for attempt in 1:10
usermsg = usermsg = """
"""
Your ongoing conversation with the user: $chathistory Your ongoing conversation with the user: $chathistory
$context $context
Your thoughts: $(a.memory[:CHATBOX]) Your thoughts: $(a.memory[:CHATBOX])
@@ -1107,20 +1101,19 @@ function generatechat(a::sommelier)
_prompt = _prompt =
[ [
Dict(:name=> "system", :text=> systemmsg), Dict(:name => "system", :text => systemmsg),
Dict(:name=> "user", :text=> usermsg) Dict(:name => "user", :text => usermsg)
] ]
# put in model format # put in model format
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct") prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct")
prompt *= prompt *= """
"""
<|start_header_id|>assistant<|end_header_id|> <|start_header_id|>assistant<|end_header_id|>
""" """
try try
response = a.text2textInstructLLM(prompt) response = a.text2textInstructLLM(prompt)
responsedict = GeneralUtils.textToDict(response,["Mentioning_wine", "Chat"], responsedict = GeneralUtils.textToDict(response, ["Mentioning_wine", "Chat"],
rightmarker=":", symbolkey=true, lowercasekey=true) rightmarker=":", symbolkey=true, lowercasekey=true)
for i [:chat] for i [:chat]
@@ -1149,12 +1142,12 @@ function generatechat(a::sommelier)
isMemEmpty = isempty(a.memory[:shortmem]) isMemEmpty = isempty(a.memory[:shortmem])
if occursin("Yes", responsedict[:mentioning_wine]) && isMemEmpty if occursin("Yes", responsedict[:mentioning_wine]) && isMemEmpty
errornote = "Note: You can't recommend wines yet. You must check your inventory before recommending wine to the user." errornote = "Note: You can't recommend wines yet. You must check your inventory before recommending wine to the user."
error( "You must check your inventory before recommending wine") error("You must check your inventory before recommending wine")
elseif occursin("(check", responsedict[:chat]) || occursin("*check", responsedict[:chat]) || elseif occursin("(check", responsedict[:chat]) || occursin("*check", responsedict[:chat]) ||
occursin("inventory)", responsedict[:chat]) || occursin("inventory*", responsedict[:chat]) occursin("inventory)", responsedict[:chat]) || occursin("inventory*", responsedict[:chat])
errornote = "Note: You can't recommend wines yet. You must check your inventory before recommending wine to the user." errornote = "Note: You can't recommend wines yet. You must check your inventory before recommending wine to the user."
error( "You must check your inventory before recommending wine") error("You must check your inventory before recommending wine")
else else
errornote = "" errornote = ""
end end
@@ -1176,8 +1169,7 @@ function generatechat(a::sommelier)
end end
function generatechat(a::companion) function generatechat(a::companion)
systemmsg = systemmsg = """
"""
Your name is $(a.name). You are a helpful assistant. Your name is $(a.name). You are a helpful assistant.
You are currently talking with the user. You are currently talking with the user.
Your goal includes: Your goal includes:
@@ -1204,22 +1196,20 @@ function generatechat(a::companion)
noise = "" noise = ""
for attempt in 1:10 for attempt in 1:10
usermsg = usermsg = """
"""
Your ongoing conversation with the user: $chathistory Your ongoing conversation with the user: $chathistory
$noise $noise
""" """
_prompt = _prompt =
[ [
Dict(:name=> "system", :text=> systemmsg), Dict(:name => "system", :text => systemmsg),
Dict(:name=> "user", :text=> usermsg) Dict(:name => "user", :text => usermsg)
] ]
# put in model format # put in model format
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct") prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct")
prompt *= prompt *= """
"""
<|start_header_id|>assistant<|end_header_id|> <|start_header_id|>assistant<|end_header_id|>
""" """
@@ -1228,7 +1218,7 @@ function generatechat(a::companion)
println("\n~~~ generatechat() ", @__FILE__, " ", @__LINE__) println("\n~~~ generatechat() ", @__FILE__, " ", @__LINE__)
pprintln(response) pprintln(response)
responsedict = GeneralUtils.textToDict(response,["Chat"], responsedict = GeneralUtils.textToDict(response, ["Chat"],
rightmarker=":", symbolkey=true, lowercasekey=true) rightmarker=":", symbolkey=true, lowercasekey=true)
result = responsedict[:chat] result = responsedict[:chat]
@@ -1293,8 +1283,7 @@ function generatequestion(a, text2textInstructLLM::Function; recent=nothing)::St
# Let's begin! # Let's begin!
# """ # """
systemmsg = systemmsg = """
"""
Your name is $(a.name). You are a helpful assistant acting as a polite, website-based sommelier for $(a.retailername)'s online store. Your name is $(a.name). You are a helpful assistant acting as a polite, website-based sommelier for $(a.retailername)'s online store.
Your goal includes: Your goal includes:
1) Help the user select the best wines from your inventory that align with the user's preferences 1) Help the user select the best wines from your inventory that align with the user's preferences
@@ -1342,6 +1331,9 @@ function generatequestion(a, text2textInstructLLM::Function; recent=nothing)::St
... ...
Here are some examples: Here are some examples:
Q: Why the user saying this?
A: According to the situation, ...
Q: The user is asking for a cappuccino. Do I have it at my cafe? Q: The user is asking for a cappuccino. Do I have it at my cafe?
A: No I don't. A: No I don't.
@@ -1351,17 +1343,26 @@ function generatequestion(a, text2textInstructLLM::Function; recent=nothing)::St
Q: Are they allergic to milk? Q: Are they allergic to milk?
A: According to the situation, since they mentioned a cappuccino before, it seems they are not allergic to milk. A: According to the situation, since they mentioned a cappuccino before, it seems they are not allergic to milk.
Q: Have I searched the database yet? Q: Have I searched the inventory yet?
A: According to the situation, no. I need more information. A: According to the situation, no. I need more information.
Q: Did I found something in the database? Q: Should I check the inventory now?
A: According to the situation, ...
Q: What do I have in the inventory?
A: According to the situation, ... A: According to the situation, ...
Q: Which items are within the user price range? And which items are out of the user price rance? Q: Which items are within the user price range? And which items are out of the user price rance?
A: According to the situation, ... A: According to the situation, ...
Q: Do I have what the user wants in stock?
A: According to the situation, ...
Q: Did I introduce the coffee blend varieties to the user yet? Q: Did I introduce the coffee blend varieties to the user yet?
A: According to the situation, no, I didn't because I have not searched the database yet. A: According to the situation, no, I didn't because I have not searched the inventory yet.
Q: Am I certain about the information I'm going to share with the user, or should I verify the information first?
A: According to the situation, ...
Let's begin! Let's begin!
""" """
@@ -1369,7 +1370,7 @@ function generatequestion(a, text2textInstructLLM::Function; recent=nothing)::St
totalevents = length(a.memory[:events]) totalevents = length(a.memory[:events])
ind = ind =
if totalevents > recent if totalevents > recent
start = totalevents-recent start = totalevents - recent
start:totalevents start:totalevents
else else
1:totalevents 1:totalevents
@@ -1387,8 +1388,7 @@ function generatequestion(a, text2textInstructLLM::Function; recent=nothing)::St
response = nothing # store for show when error msg show up response = nothing # store for show when error msg show up
for attempt in 1:10 for attempt in 1:10
usermsg = usermsg = """
"""
Recap: $(a.memory[:recap]) Recap: $(a.memory[:recap])
Your recent events: $timeline Your recent events: $timeline
$errornote $errornote
@@ -1396,14 +1396,13 @@ function generatequestion(a, text2textInstructLLM::Function; recent=nothing)::St
_prompt = _prompt =
[ [
Dict(:name=> "system", :text=> systemmsg), Dict(:name => "system", :text => systemmsg),
Dict(:name=> "user", :text=> usermsg) Dict(:name => "user", :text => usermsg)
] ]
# put in model format # put in model format
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct") prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct")
prompt *= prompt *= """
"""
<|start_header_id|>assistant<|end_header_id|> <|start_header_id|>assistant<|end_header_id|>
""" """
@@ -1413,10 +1412,10 @@ function generatequestion(a, text2textInstructLLM::Function; recent=nothing)::St
if q_number < 3 if q_number < 3
error("too few questions only $q_number questions are generated ", @__FILE__, " ", @__LINE__) error("too few questions only $q_number questions are generated ", @__FILE__, " ", @__LINE__)
# check whether "A1" is in the response, if not error. # check whether "A1" is in the response, if not error.
elseif !occursin("A1", response) elseif !occursin("A1:", response)
error("no answer found in the response ", @__FILE__, " ", @__LINE__) error("no answer found in the response ", @__FILE__, " ", @__LINE__)
end end
# response = string(split(response, "Please")[1]) # LLM usually add comments which is no need.
responsedict = GeneralUtils.textToDict(response, responsedict = GeneralUtils.textToDict(response,
["Understanding", "Q1"], ["Understanding", "Q1"],
rightmarker=":", symbolkey=true, lowercasekey=true) rightmarker=":", symbolkey=true, lowercasekey=true)
@@ -1429,7 +1428,7 @@ function generatequestion(a, text2textInstructLLM::Function; recent=nothing)::St
showerror(io, e) showerror(io, e)
errorMsg = String(take!(io)) errorMsg = String(take!(io))
st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace())) st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
println("\n Attempt $attempt. Error occurred: $errorMsg\n$st ", @__FILE__, " ", @__LINE__) println("\nAttempt $attempt. Error occurred: $errorMsg\n$st ", @__FILE__, " ", @__LINE__)
end end
end end
error("generatequestion failed to generate a thought ", response) error("generatequestion failed to generate a thought ", response)
@@ -1597,7 +1596,7 @@ end
# end # end
function generateSituationReport(a, text2textInstructLLM::Function; skiprecent::Integer=0 function generateSituationReport(a, text2textInstructLLM::Function; skiprecent::Integer=0
)::Dict )::Dict
# systemmsg = # systemmsg =
# """ # """
@@ -1619,8 +1618,7 @@ function generateSituationReport(a, text2textInstructLLM::Function; skiprecent::
# Let's begin! # Let's begin!
# """ # """
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 for each event in an ongoing, interleaving series. Your task is to writes a summary for each event in an ongoing, interleaving series.
@@ -1645,7 +1643,7 @@ function generateSituationReport(a, text2textInstructLLM::Function; skiprecent::
""" """
if length(a.memory[:events]) <= skiprecent if length(a.memory[:events]) <= skiprecent
return Dict(:recap=> "None") return Dict(:recap => "None")
end end
events = deepcopy(a.memory[:events][1:end-skiprecent]) events = deepcopy(a.memory[:events][1:end-skiprecent])
@@ -1663,8 +1661,7 @@ function generateSituationReport(a, text2textInstructLLM::Function; skiprecent::
response = nothing # store for show when error msg show up response = nothing # store for show when error msg show up
for attempt in 1:10 for attempt in 1:10
usermsg = usermsg = """
"""
Total events: $(length(events)) Total events: $(length(events))
Events timeline: $timeline Events timeline: $timeline
$errornote $errornote
@@ -1672,14 +1669,13 @@ function generateSituationReport(a, text2textInstructLLM::Function; skiprecent::
_prompt = _prompt =
[ [
Dict(:name=> "system", :text=> systemmsg), Dict(:name => "system", :text => systemmsg),
Dict(:name=> "user", :text=> usermsg) Dict(:name => "user", :text => usermsg)
] ]
# put in model format # put in model format
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct") prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct")
prompt *= prompt *= """
"""
<|start_header_id|>assistant<|end_header_id|> <|start_header_id|>assistant<|end_header_id|>
""" """
@@ -1687,9 +1683,10 @@ function generateSituationReport(a, text2textInstructLLM::Function; skiprecent::
# responsedict = GeneralUtils.textToDict(response, # responsedict = GeneralUtils.textToDict(response,
# ["summary", "presented", "selected"], # ["summary", "presented", "selected"],
# rightmarker=":", symbolkey=true) # rightmarker=":", symbolkey=true)
# println("--> generateSituationReport ", @__FILE__, " ", @__LINE__) println("\n~~~ generateSituationReport() ", @__FILE__, " ", @__LINE__)
pprintln(response) pprintln(response)
eventcount = count("Event_", response) eventcount = count("Event_", response)
# if eventcount < (length(events)) # if eventcount < (length(events))
@@ -1698,7 +1695,7 @@ function generateSituationReport(a, text2textInstructLLM::Function; skiprecent::
# else # else
# return Dict(:recap=> response) # return Dict(:recap=> response)
# end # end
return Dict(:recap=> response) return Dict(:recap => response)
end end
error("generateSituationReport failed to generate a thought ", response) error("generateSituationReport failed to generate a thought ", response)
end end