update
This commit is contained in:
+136
-66
@@ -48,6 +48,7 @@ macro executeStringFunction(functionStr, args...)
|
||||
end
|
||||
|
||||
|
||||
|
||||
""" Think and choose action
|
||||
|
||||
# Arguments
|
||||
@@ -125,12 +126,11 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
|
||||
# recentevents_ind = GeneralUtils.recentElementsIndex(
|
||||
# length(a.memory["events"]), recentevents; includelatest=true)
|
||||
|
||||
requiredKeys = ["plan", "actionname", "actioninput"]
|
||||
|
||||
requiredKeys = ["plan", "action_name", "action_input"]
|
||||
context =
|
||||
"""
|
||||
<internal_context_for_assistant>
|
||||
$(a.memory["shortmem"]["scratchpad"])
|
||||
$(GeneralUtils.dict_to_string_html(a.memory["shortmem"]))
|
||||
</internal_context_for_assistant>
|
||||
"""
|
||||
|
||||
@@ -179,9 +179,9 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
|
||||
continue
|
||||
end
|
||||
|
||||
if responsedict["actionname"] ∉ ["CHATBOX", "CHECKWINE", "PRESENTBOX", "ENDCONVERSATION"]
|
||||
if responsedict["action_name"] ∉ ["CHATBOX", "CHECKWINE", "PRESENTBOX", "ENDCONVERGUIDELINE"]
|
||||
errornote = "Your previous attempt didn't use the given functions"
|
||||
println("\nERROR YiemAgent decisionMaker() $errornote --(not qualify response)--> $(responsedict["actionname"])", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
println("\nERROR YiemAgent decisionMaker() $errornote --(not qualify response)--> $(responsedict["action_name"])", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
continue
|
||||
end
|
||||
|
||||
@@ -216,8 +216,8 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
|
||||
|
||||
# delete!(responsedict, :mentioned_winery)
|
||||
|
||||
# check whether responsedict["actioninput"] is the same as previous dialogue
|
||||
# if !isempty(a.chathistory) && responsedict["actioninput"] == a.chathistory[end]["text"]
|
||||
# check whether responsedict["action_input"] is the same as previous dialogue
|
||||
# if !isempty(a.chathistory) && responsedict["action_input"] == a.chathistory[end]["text"]
|
||||
# errornote = "In your previous attempt, you repeated the previous dialogue. Please try again."
|
||||
# println("\nERROR YiemAgent decisionMaker() $response ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
# continue
|
||||
@@ -317,16 +317,16 @@ function evaluator(a::T1, timeline, decisiondict, evaluateecontext
|
||||
- evaluatee_context: The context that evaluatee use to make a decision
|
||||
- evaluatee_decision: The decision made by the evaluatee, consists of the following elements:
|
||||
"plan" is the trainee's plan
|
||||
"actionname" is the name of the action taken, which can be one of the available tool name.
|
||||
"actioninput" is the input to the action.
|
||||
"action_name" is the name of the action taken, which can be one of the available tool name.
|
||||
"action_input" is the input to the action.
|
||||
</At each round of conversation, you will be given the following information>
|
||||
<You must follow the following policy>
|
||||
- Use only infomation provided by the store policy and guidelines as a bedrocks for your response.
|
||||
</You must follow the following policy>
|
||||
<You should follow the following guidelines>
|
||||
- The trainee's plan, actionname, and actioninput must be logically consistent
|
||||
- The trainee's actioninput should be in a proper format as specified by the tools.
|
||||
- The trainee's action name and action input should make sense. For example, if the trainee isn't finished talking, he shouldn't use the ENDCONVERSATION tool.
|
||||
- The trainee's plan, action_name, and action_input must be logically consistent
|
||||
- The trainee's action_input should be in a proper format as specified by the tools.
|
||||
- The trainee's action name and action input should make sense. For example, if the trainee isn't finished talking, he shouldn't use the ENDCONVERGUIDELINE tool.
|
||||
</You should follow the following guidelines>
|
||||
<You should then respond to the user with>
|
||||
1) trajectory_evaluation: Analyze the trajectory of a solution to answer the user's original question.
|
||||
@@ -368,7 +368,7 @@ function evaluator(a::T1, timeline, decisiondict, evaluateecontext
|
||||
$evaluateecontext
|
||||
</evaluatee_context>
|
||||
<evaluatee_decision>
|
||||
{plan: $(decisiondict["plan"]), actionname: $(decisiondict["actionname"]), actioninput: $(decisiondict["actioninput"])}
|
||||
{plan: $(decisiondict["plan"]), action_name: $(decisiondict["action_name"]), action_input: $(decisiondict["action_input"])}
|
||||
</evaluatee_decision>
|
||||
P.S. $errornote
|
||||
</context>
|
||||
@@ -483,7 +483,7 @@ function conversation(a::sommelier; userinput::Union{Dict{String, Any}, JSON.Obj
|
||||
end
|
||||
|
||||
# place holder
|
||||
actionname = nothing
|
||||
action_name = nothing
|
||||
result = nothing
|
||||
chatresponse = nothing
|
||||
|
||||
@@ -498,8 +498,8 @@ function conversation(a::sommelier; userinput::Union{Dict{String, Any}, JSON.Obj
|
||||
# thinking loop until AI wants to communicate with the user
|
||||
chatresponse = nothing
|
||||
while chatresponse === nothing
|
||||
actionname, result = think(a)
|
||||
if actionname ∈ ["CHATBOX", "PRESENTBOX", "ENDCONVERSATION"]
|
||||
action_name, result = think(a)
|
||||
if action_name ∈ ["CHATBOX"]
|
||||
chatresponse = result
|
||||
end
|
||||
end
|
||||
@@ -532,8 +532,8 @@ function conversation(a::Union{companion, virtualcustomer}, userinput::Dict;
|
||||
event_description="the user talks to the assistant.",
|
||||
timestamp=Dates.now(),
|
||||
subject="user",
|
||||
actionname="CHATBOX",
|
||||
actioninput=userinput["text"],
|
||||
action_name="CHATBOX",
|
||||
action_input=userinput["text"],
|
||||
)
|
||||
)
|
||||
chatresponse = generatechat(a; converPartnerName=converPartnerName, recentEventNum=20)
|
||||
@@ -545,8 +545,8 @@ function conversation(a::Union{companion, virtualcustomer}, userinput::Dict;
|
||||
event_description="the assistant talks to the user.",
|
||||
timestamp=Dates.now(),
|
||||
subject="assistant",
|
||||
actionname="CHATBOX",
|
||||
actioninput=chatresponse,
|
||||
action_name="CHATBOX",
|
||||
action_input=chatresponse,
|
||||
)
|
||||
)
|
||||
return chatresponse
|
||||
@@ -564,20 +564,20 @@ julia>
|
||||
```
|
||||
|
||||
"""
|
||||
function think(a::T)::NamedTuple{(:actionname, :result),Tuple{String,String}} where {T<:agent}
|
||||
function think(a::T)::Union{NamedTuple{(:action_name, :result), Tuple{String, String}}, NamedTuple{(:action_name, :result), Tuple{String, Nothing}}} where {T<:agent}
|
||||
# a.memory[:recap] = generateSituationReport(a, a.context["text"2textInstructLLM]; skiprecent=0)
|
||||
thoughtDict = decisionMaker(a)
|
||||
|
||||
# # map action and input() to llm function
|
||||
# response =
|
||||
# if thoughtDict["actionname"] == "CHATBOX" || thoughtDict["actionname"] == "ENDCONVERSATION"
|
||||
# if thoughtDict["action_name"] == "CHATBOX" || thoughtDict["action_name"] == "ENDCONVERGUIDELINE"
|
||||
# (result=thoughtDict["plan"], errormsg=nothing, success=true)
|
||||
# elseif thoughtDict["actionname"] == "CHECKWINE"
|
||||
# checkwine(a, thoughtDict["actioninput"])
|
||||
# elseif thoughtDict["actionname"] == "PRESENTBOX"
|
||||
# (result=thoughtDict["actioninput"], errormsg=nothing, success=true)
|
||||
# elseif thoughtDict["action_name"] == "CHECKWINE"
|
||||
# checkwine(a, thoughtDict["action_input"])
|
||||
# elseif thoughtDict["action_name"] == "PRESENTBOX"
|
||||
# (result=thoughtDict["action_input"], errormsg=nothing, success=true)
|
||||
# else
|
||||
# error("undefined LLM function. Requesting $(thoughtDict["actionname"])")
|
||||
# error("undefined LLM function. Requesting $(thoughtDict["action_name"])")
|
||||
# end
|
||||
|
||||
# # this section allow LLM functions above to have different return values.
|
||||
@@ -590,52 +590,52 @@ function think(a::T)::NamedTuple{(:actionname, :result),Tuple{String,String}} wh
|
||||
# success::Bool = haskey(response, "success") ? response["success"] : false
|
||||
|
||||
result = nothing
|
||||
if thoughtDict["actionname"] ∈ ["CHATBOX"]
|
||||
result = thoughtDict["actioninput"]
|
||||
elseif thoughtDict["actionname"] ∈ ["ENDCONVERSATION"]
|
||||
# WORKING add ENDCONVERSATION guideline in to scratchpad
|
||||
guideline =
|
||||
if thoughtDict["action_name"] ∈ ["CHATBOX"]
|
||||
result = thoughtDict["action_input"]
|
||||
elseif thoughtDict["action_name"] == "ENDCONVERGUIDELINE"
|
||||
|
||||
# add ENDCONVERGUIDELINE guideline in to scratchpad
|
||||
endconversation_guideline =
|
||||
"""
|
||||
To end conversation with the user
|
||||
<end_conversation_guideline>
|
||||
- Provide customer with store contact info and business hours
|
||||
- Invite customer to comeback
|
||||
</end_conversation_guideline>
|
||||
<store_info>
|
||||
Business Hours: everyday 9.00-20.00
|
||||
Tel. 0863055790
|
||||
</store_info>
|
||||
"""
|
||||
|
||||
a.memory["shortmem"]["scratchpad"] =
|
||||
result = chatresponse
|
||||
elseif thoughtDict["actionname"] ∈ ["PRESENTBOX"]
|
||||
chatresponse = presentbox(a, thoughtDict) #PENDING
|
||||
result = chatresponse
|
||||
|
||||
elseif thoughtDict["actionname"] == "CHECKWINE"
|
||||
if rawresponse !== nothing
|
||||
vd = GeneralUtils.dfToVectorDict(rawresponse) # comes in dataframe format
|
||||
# a.memory["shortmem"]["found_wine"] = vd # used by decisionMaker() as a short note
|
||||
#[PENDING] a.memory["shortmem"]["available_wine"] should be OrderedDict instead of vector dict so that no duplicate item are listed?
|
||||
if length(a.memory["shortmem"]["db_search_result"]) != 0
|
||||
a.memory["shortmem"]["db_search_result"] = vcat(a.memory["shortmem"]["db_search_result"], vd)
|
||||
thoughtDict["action_result"] = endconversation_guideline
|
||||
max_ind =
|
||||
if length(a.memory["shortmem"]) == 0
|
||||
0
|
||||
else
|
||||
a.memory["shortmem"]["db_search_result"] = vd
|
||||
k = keys(a.memory["shortmem"])
|
||||
maximum(parse.(Int, k))
|
||||
end
|
||||
a.memory["shortmem"]["$(max_ind + 1)"] = thoughtDict
|
||||
|
||||
# # add to scratchpad
|
||||
# a.memory["shortmem"]["scratchpad"] *=
|
||||
# """
|
||||
# <database_search_result>
|
||||
# I searched the database with this search term: $actioninput \nThis is what I found: $result
|
||||
# </database_search_result>
|
||||
# """
|
||||
else
|
||||
# a.memory["shortmem"]["scratchpad"] *=
|
||||
# """
|
||||
# <database_search_result>
|
||||
# I searched the database with this search term: $actioninput \nThis is what I found: $result
|
||||
# </database_search_result>
|
||||
# """
|
||||
end
|
||||
elseif thoughtDict["action_name"] ∈ ["PRESENTBOX"] #PENDING
|
||||
chatresponse = presentbox(a, thoughtDict)
|
||||
result = chatresponse
|
||||
|
||||
elseif thoughtDict["action_name"] == "CHECKWINE"
|
||||
df = checkwine(a, thoughtDict["action_input"])
|
||||
thoughtDict["action_result"] = GeneralUtils.dfToString(df)
|
||||
max_ind =
|
||||
if length(a.memory["shortmem"]) == 0
|
||||
0
|
||||
else
|
||||
k = keys(a.memory["shortmem"])
|
||||
maximum(parse.(Int, k))
|
||||
end
|
||||
a.memory["shortmem"]["$(max_ind + 1)"] = thoughtDict
|
||||
else
|
||||
error("condition is not defined ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
end
|
||||
|
||||
return (actionname=thoughtDict["actionname"], result=result)
|
||||
return (action_name=thoughtDict["action_name"], result=result)
|
||||
end
|
||||
|
||||
|
||||
@@ -697,7 +697,7 @@ function presentbox(a::sommelier, thoughtDict; maxtattempt::Integer=10, recentev
|
||||
context =
|
||||
"""
|
||||
<context>
|
||||
Name of the wines that needs to be introduced: $(thoughtDict["actioninput"])
|
||||
Name of the wines that needs to be introduced: $(thoughtDict["action_input"])
|
||||
$(a.memory["shortmem"]["scratchpad"])
|
||||
P.S. $errornote
|
||||
</context>
|
||||
@@ -1333,4 +1333,74 @@ function detectWineryName(a, text)
|
||||
|
||||
|
||||
|
||||
end # module interface
|
||||
end # module interface
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user