update
This commit is contained in:
@@ -205,20 +205,20 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
|
||||
</at each round of conversation, you will be given the following information>
|
||||
<you should then respond to the user with interleaving Plan, Action_name, Action_input>
|
||||
1) plan: Based on the current situation, state a complete action plan to complete the task. Be specific.
|
||||
2) action_name: (Typically corresponds to the execution of the first step in your plan) Can be one of the available tool name
|
||||
3) action_input: The input to the action you are about to perform according to your plan.
|
||||
2) actionname: (Typically corresponds to the execution of the first step in your plan) Can be one of the available tool name
|
||||
3) actioninput: The input to the action you are about to perform according to your plan.
|
||||
</you should then respond to the user with interleaving Plan, Action_name, Action_input>
|
||||
<you should only respond in format as described below>
|
||||
{
|
||||
"plan": "...",
|
||||
"action_name": "...",
|
||||
"action_input": "..."
|
||||
"actionname": "...",
|
||||
"actioninput": "..."
|
||||
}
|
||||
</you should only respond in format as described below>
|
||||
|
||||
Let's begin!
|
||||
"""
|
||||
requiredKeys = [:plan, :action_name, :action_input]
|
||||
requiredKeys = [:plan, :actionname, :actioninput]
|
||||
# database_search_result =
|
||||
# if length(a.memory[:shortmem][:db_search_result]) != 0
|
||||
# availableWineToText(a.memory[:shortmem][:db_search_result])
|
||||
@@ -347,9 +347,9 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
|
||||
# responsedict = GeneralUtils.textToDict(response, header;
|
||||
# dictKey=dictkey, symbolkey=true)
|
||||
|
||||
if responsedict[:action_name] ∉ ["CHATBOX", "CHECKWINE", "PRESENTBOX", "ENDCONVERSATION"]
|
||||
if responsedict[:actionname] ∉ ["CHATBOX", "CHECKWINE", "PRESENTBOX", "ENDCONVERSATION"]
|
||||
errornote = "Your previous attempt didn't use the given functions"
|
||||
println("\nERROR YiemAgent decisionMaker() $errornote --(not qualify response)--> $(responsedict[:action_name])", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
println("\nERROR YiemAgent decisionMaker() $errornote --(not qualify response)--> $(responsedict[:actionname])", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
continue
|
||||
end
|
||||
|
||||
@@ -377,12 +377,12 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
|
||||
# end
|
||||
# checkFlag == true ? continue : nothing
|
||||
|
||||
# # check if action_name = CHECKINVENTORY and action_input has the words "pairs well" or
|
||||
# # check if actionname = CHECKINVENTORY and actioninput has the words "pairs well" or
|
||||
# # "pair well" in it because it is not a valid query.
|
||||
# detected_kw = GeneralUtils.detect_keyword(["pair", "pairs", "pairing", "well"], responsedict[:action_input])
|
||||
# if responsedict[:action_name] == "CHECKINVENTORY" && sum(values(detected_kw)) != 0
|
||||
# errornote = "In your previous attempt, action_input for CHECKINVENTORY function was $(responsedict[:action_name]). It was not specific enough."
|
||||
# println("\nERROR YiemAgent decisionMaker() $errornote => $(responsedict[:action_input]) ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
# detected_kw = GeneralUtils.detect_keyword(["pair", "pairs", "pairing", "well"], responsedict[:actioninput])
|
||||
# if responsedict[:actionname] == "CHECKINVENTORY" && sum(values(detected_kw)) != 0
|
||||
# errornote = "In your previous attempt, actioninput for CHECKINVENTORY function was $(responsedict[:actionname]). It was not specific enough."
|
||||
# println("\nERROR YiemAgent decisionMaker() $errornote => $(responsedict[:actioninput]) ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
# continue
|
||||
# end
|
||||
|
||||
@@ -417,8 +417,8 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
|
||||
|
||||
delete!(responsedict, :mentioned_winery)
|
||||
|
||||
# check whether responsedict[:action_input] is the same as previous dialogue
|
||||
if !isempty(a.chathistory) && responsedict[:action_input] == a.chathistory[end][:text]
|
||||
# check whether responsedict[:actioninput] is the same as previous dialogue
|
||||
if !isempty(a.chathistory) && responsedict[:actioninput] == 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
|
||||
@@ -542,7 +542,7 @@ end
|
||||
# else
|
||||
|
||||
# header = ["Thought:", "Plan:", "Action_name:", "Action_input:"]
|
||||
# dictkey = ["thought", "plan", "action_name", "action_input"]
|
||||
# dictkey = ["thought", "plan", "actionname", "actioninput"]
|
||||
|
||||
# context = # may b add wine name instead of the hold wine data is better
|
||||
# if length(a.memory[:shortmem][:available_wine]) != 0
|
||||
@@ -653,8 +653,8 @@ end
|
||||
# # d = Dict(
|
||||
# # :thought=> "The user is looking for a wine tahat matches their intention and budget. I've checked the inventory and found wines that match the customer's criteria. I will present the wines to the customer.",
|
||||
# # :plan=> "1) I'll provide detailed introductions of the wines I just found to the user. 2) I'll explain how the wine could match the user's intention and what its effects might mean for the user's experience. 3) If multiple wines are available, I'll highlight their differences and provide a comprehensive comparison of how each option aligns with the user's intention and what the potential effects of each option could mean for the user's experience. 4) I'll provide my personal recommendation.",
|
||||
# # :action_name=> "PRESENTBOX",
|
||||
# # :action_input=> "I need to present to the user the following wines: $winenames")
|
||||
# # :actionname=> "PRESENTBOX",
|
||||
# # :actioninput=> "I need to present to the user the following wines: $winenames")
|
||||
# # a.memory[:shortmem][:found_wine] = [] # clear because PRESENTBOX command is issued. This is to prevent decisionMaker() keep presenting the same wines
|
||||
# # result = (systemmsg=systemmsg, usermsg=usermsg, unformatPrompt=unformatPrompt, result=d)
|
||||
# # println("\nYiem decisionMaker() ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
@@ -704,7 +704,7 @@ end
|
||||
# responsedict = GeneralUtils.textToDict(response, header;
|
||||
# dictKey=dictkey, symbolkey=true)
|
||||
|
||||
# if responsedict[:action_name] ∉ ["CHATBOX", "CHECKINVENTORY", "PRESENTBOX", "ENDCONVERSATION"]
|
||||
# if responsedict[:actionname] ∉ ["CHATBOX", "CHECKINVENTORY", "PRESENTBOX", "ENDCONVERSATION"]
|
||||
# errornote = "Your previous attempt didn't use the given functions"
|
||||
# println("\nERROR YiemAgent decisionMaker() $errornote ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
# continue
|
||||
@@ -734,11 +734,11 @@ end
|
||||
# end
|
||||
# checkFlag == true ? continue : nothing
|
||||
|
||||
# # check if action_name = CHECKINVENTORY and action_input has the words "pairs well" or
|
||||
# # check if actionname = CHECKINVENTORY and actioninput has the words "pairs well" or
|
||||
# # "pair well" in it because it is not a valid query.
|
||||
# detected_kw = GeneralUtils.detect_keyword(["pair", "pairs", "pairing", "well"], responsedict[:action_input])
|
||||
# if responsedict[:action_name] == "CHECKINVENTORY" && sum(values(detected_kw)) != 0
|
||||
# errornote = "In your previous attempt, action_input for CHECKINVENTORY function is invalid"
|
||||
# detected_kw = GeneralUtils.detect_keyword(["pair", "pairs", "pairing", "well"], responsedict[:actioninput])
|
||||
# if responsedict[:actionname] == "CHECKINVENTORY" && sum(values(detected_kw)) != 0
|
||||
# errornote = "In your previous attempt, actioninput for CHECKINVENTORY function is invalid"
|
||||
# println("\nERROR YiemAgent decisionMaker() $errornote ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
# continue
|
||||
# end
|
||||
@@ -777,8 +777,8 @@ end
|
||||
# responsedict[:unformatPrompt] = unformatPrompt
|
||||
# responsedict[:QandA] = QandA
|
||||
|
||||
# # check whether responsedict[:action_input] is the same as previous dialogue
|
||||
# if responsedict[:action_input] == a.chathistory[end][:text]
|
||||
# # check whether responsedict[:actioninput] is the same as previous dialogue
|
||||
# if responsedict[:actioninput] == 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
|
||||
@@ -835,15 +835,15 @@ 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
|
||||
"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.
|
||||
"actionname" is the name of the action taken, which can be one of the available tool name.
|
||||
"actioninput" 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, 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 plan, actionname, and actioninput must be logically consistent
|
||||
- The trainee's actioninput should be in a proper format as specified by the tools.
|
||||
</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.
|
||||
@@ -885,7 +885,7 @@ function evaluator(a::T1, timeline, decisiondict, evaluateecontext
|
||||
$evaluateecontext
|
||||
</evaluatee_context>
|
||||
<evaluatee_decision>
|
||||
{plan: $(decisiondict[:plan]), action_name: $(decisiondict[:action_name]), action_input: $(decisiondict[:action_input])}
|
||||
{plan: $(decisiondict[:plan]), actionname: $(decisiondict[:actionname]), actioninput: $(decisiondict[:actioninput])}
|
||||
</evaluatee_decision>
|
||||
P.S. $errornote
|
||||
</context>
|
||||
@@ -1056,8 +1056,8 @@ function conversation(a::sommelier; userinput::Union{Dict, Nothing}=nothing,
|
||||
event_description="the user talks to the assistant.",
|
||||
timestamp=Dates.now(),
|
||||
subject="user",
|
||||
action_name="CHATBOX",
|
||||
action_input=userinput[:text],
|
||||
actionname="CHATBOX",
|
||||
actioninput=userinput[:text],
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1094,8 +1094,8 @@ function conversation(a::Union{companion, virtualcustomer}, userinput::Dict;
|
||||
event_description="the user talks to the assistant.",
|
||||
timestamp=Dates.now(),
|
||||
subject="user",
|
||||
action_name="CHATBOX",
|
||||
action_input=userinput[:text],
|
||||
actionname="CHATBOX",
|
||||
actioninput=userinput[:text],
|
||||
)
|
||||
)
|
||||
chatresponse = generatechat(a; converPartnerName=converPartnerName, recentEventNum=20)
|
||||
@@ -1107,8 +1107,8 @@ function conversation(a::Union{companion, virtualcustomer}, userinput::Dict;
|
||||
event_description="the assistant talks to the user.",
|
||||
timestamp=Dates.now(),
|
||||
subject="assistant",
|
||||
action_name="CHATBOX",
|
||||
action_input=chatresponse,
|
||||
actionname="CHATBOX",
|
||||
actioninput=chatresponse,
|
||||
)
|
||||
)
|
||||
return chatresponse
|
||||
@@ -1135,8 +1135,8 @@ function think(a::T)::NamedTuple{(:actionname, :result),Tuple{String,String}} wh
|
||||
# a.memory[:recap] = generateSituationReport(a, a.func[:text2textInstructLLM]; skiprecent=0)
|
||||
thoughtDict = decisionMaker(a)
|
||||
|
||||
actionname = thoughtDict[:action_name]
|
||||
actioninput = thoughtDict[:action_input]
|
||||
actionname = thoughtDict[:actionname]
|
||||
actioninput = thoughtDict[:actioninput]
|
||||
|
||||
# map action and input() to llm function
|
||||
response =
|
||||
@@ -1183,8 +1183,8 @@ function think(a::T)::NamedTuple{(:actionname, :result),Tuple{String,String}} wh
|
||||
timestamp=Dates.now(),
|
||||
subject="assistant",
|
||||
thought=thoughtDict,
|
||||
action_name=actionname,
|
||||
action_input=actioninput,
|
||||
actionname=actionname,
|
||||
actioninput=actioninput,
|
||||
)
|
||||
)
|
||||
result = actioninput
|
||||
@@ -1209,8 +1209,8 @@ function think(a::T)::NamedTuple{(:actionname, :result),Tuple{String,String}} wh
|
||||
timestamp=Dates.now(),
|
||||
subject="assistant",
|
||||
thought=thoughtDict,
|
||||
action_name=actionname,
|
||||
action_input=chatresponse,
|
||||
actionname=actionname,
|
||||
actioninput=chatresponse,
|
||||
)
|
||||
)
|
||||
result = chatresponse
|
||||
@@ -1248,8 +1248,8 @@ function think(a::T)::NamedTuple{(:actionname, :result),Tuple{String,String}} wh
|
||||
timestamp= Dates.now(),
|
||||
subject= "assistant",
|
||||
thought=thoughtDict,
|
||||
action_name=actionname,
|
||||
action_input= "I search the database with this search term: $actioninput",
|
||||
actionname=actionname,
|
||||
actioninput= "I search the database with this search term: $actioninput",
|
||||
observation= "This is what I found:, $result"
|
||||
)
|
||||
)
|
||||
@@ -1320,7 +1320,7 @@ function presentbox(a::sommelier, thoughtDict; maxtattempt::Integer=10, recentev
|
||||
context =
|
||||
"""
|
||||
<context>
|
||||
Name of the wines that needs to be introduced: $(thoughtDict[:action_input])
|
||||
Name of the wines that needs to be introduced: $(thoughtDict[:actioninput])
|
||||
$(a.memory[:shortmem][:scratchpad])
|
||||
P.S. $errornote
|
||||
</context>
|
||||
@@ -1503,7 +1503,7 @@ end
|
||||
# <context>
|
||||
# Database search result: $database_search_result
|
||||
# Chat history: $chathistory
|
||||
# Name of the wines that needs to be introduced: $(thoughtDict[:action_input])
|
||||
# Name of the wines that needs to be introduced: $(thoughtDict[:actioninput])
|
||||
# P.S. $errornote
|
||||
# </context>
|
||||
# """
|
||||
|
||||
@@ -1053,7 +1053,7 @@ end
|
||||
# “action_name” is the name of the action taken, which can be one of the following functions:
|
||||
# 1) CHATBOX[text], which you can use to talk with the user. "text" is in verbal English.
|
||||
# 2) WINESTOCK[query], which you can use to find info about wine in your inventory. "query" is a search term in verbal English. The best query must includes "budget", "type of wine", "characteristics of wine" and "food pairing".
|
||||
# "action_input" is the input to the action
|
||||
# "actioninput" is the input to the action
|
||||
# "observation" is result of the preceding immediate action.
|
||||
|
||||
# At each round of conversation, the user will give you:
|
||||
|
||||
36
src/util.jl
36
src/util.jl
@@ -102,7 +102,7 @@ end
|
||||
-----
|
||||
"""
|
||||
function addNewMessage(a::T1, name::String, text::T2;
|
||||
maximumMsg::Integer=20) where {T1<:agent, T2<:AbstractString}
|
||||
maximumMsg::Integer=30) where {T1<:agent, T2<:AbstractString}
|
||||
if name ∉ ["system", "user", "assistant"] # guard against typo
|
||||
error("name is not in agent.availableRole $(@__LINE__)")
|
||||
end
|
||||
@@ -231,8 +231,8 @@ function eventdict(;
|
||||
timestamp::Union{DateTime, Nothing}=nothing,
|
||||
subject::Union{String, Nothing}=nothing,
|
||||
thought::Union{AbstractDict, Nothing}=nothing,
|
||||
action_name::Union{String, Nothing}=nothing, # "CHAT", "CHECKINVENTORY", "PRESENTBOX", etc
|
||||
action_input::Union{String, Nothing}=nothing,
|
||||
actionname::Union{String, Nothing}=nothing, # "CHAT", "CHECKINVENTORY", "PRESENTBOX", etc
|
||||
actioninput::Union{String, Nothing}=nothing,
|
||||
location::Union{String, Nothing}=nothing,
|
||||
equipment_used::Union{String, Nothing}=nothing,
|
||||
material_used::Union{String, Nothing}=nothing,
|
||||
@@ -245,8 +245,8 @@ function eventdict(;
|
||||
:timestamp=> timestamp,
|
||||
:subject=> subject,
|
||||
:thought=> thought,
|
||||
:action_name=> action_name,
|
||||
:action_input=> action_input,
|
||||
:actionname=> actionname,
|
||||
:actioninput=> actioninput,
|
||||
:location=> location,
|
||||
:equipment_used=> equipment_used,
|
||||
:material_used=> material_used,
|
||||
@@ -302,14 +302,14 @@ function createTimeline(events::T1; eventindex::Union{UnitRange, Nothing}=nothin
|
||||
event = events[i]
|
||||
# If no outcome exists, format without outcome
|
||||
# if event[:actionname] == "CHATBOX"
|
||||
# timeline *= "Event_$i $(event[:subject])> action_name: $(event[:actionname]), action_input: $(event[:actioninput])\n"
|
||||
# timeline *= "Event_$i $(event[:subject])> actionname: $(event[:actionname]), actioninput: $(event[:actioninput])\n"
|
||||
# elseif event[:actionname] == "CHECKINVENTORY" && event[:observation] === nothing
|
||||
# timeline *= "Event_$i $(event[:subject])> action_name: $(event[:actionname]), action_input: $(event[:actioninput]), observation: Not done yet.\n"
|
||||
# timeline *= "Event_$i $(event[:subject])> actionname: $(event[:actionname]), actioninput: $(event[:actioninput]), observation: Not done yet.\n"
|
||||
# If outcome exists, include it in formatting
|
||||
if event[:action_name] == "CHECKWINE"
|
||||
timeline *= "Event_$i $(event[:subject])> action_name: $(event[:action_name]), action_input: $(event[:action_input]), observation: $(event[:observation])\n"
|
||||
if event[:actionname] == "CHECKWINE"
|
||||
timeline *= "Event_$i $(event[:subject])> actionname: $(event[:actionname]), actioninput: $(event[:actioninput]), observation: $(event[:observation])\n"
|
||||
else
|
||||
timeline *= "Event_$i $(event[:subject])> action_name: $(event[:action_name]), action_input: $(event[:action_input])\n"
|
||||
timeline *= "Event_$i $(event[:subject])> actionname: $(event[:actionname]), actioninput: $(event[:actioninput])\n"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -334,10 +334,10 @@ end
|
||||
# event = events[i]
|
||||
# # If no outcome exists, format without outcome
|
||||
# if event[:observation] === nothing
|
||||
# timeline *= "Event_$i $(event[:subject])> action_name: $(event[:actionname]), action_input: $(event[:actioninput]), observation: Not done yet.\n"
|
||||
# timeline *= "Event_$i $(event[:subject])> actionname: $(event[:actionname]), actioninput: $(event[:actioninput]), observation: Not done yet.\n"
|
||||
# # If outcome exists, include it in formatting
|
||||
# else
|
||||
# timeline *= "Event_$i $(event[:subject])> action_name: $(event[:actionname]), action_input: $(event[:actioninput]), observation: $(event[:observation])\n"
|
||||
# timeline *= "Event_$i $(event[:subject])> actionname: $(event[:actionname]), actioninput: $(event[:actioninput]), observation: $(event[:observation])\n"
|
||||
# end
|
||||
# end
|
||||
|
||||
@@ -365,17 +365,17 @@ function createEventsLog(events::T1; index::Union{UnitRange, Nothing}=nothing
|
||||
# If no outcome exists, format without outcome
|
||||
if event[:observation] === nothing
|
||||
subject = event[:subject]
|
||||
action_name = event[:action_name]
|
||||
action_input = event[:action_input]
|
||||
str = "Action_name: $action_name, Action_input: $action_input"
|
||||
actionname = event[:actionname]
|
||||
actioninput = event[:actioninput]
|
||||
str = "actionname: $actionname, actioninput: $actioninput"
|
||||
d = Dict{Symbol, String}(:name=>subject, :text=>str)
|
||||
push!(log, d)
|
||||
else
|
||||
subject = event[:subject]
|
||||
action_name = event[:action_name]
|
||||
action_input = event[:action_input]
|
||||
actionname = event[:actionname]
|
||||
actioninput = event[:actioninput]
|
||||
observation = event[:observation]
|
||||
str = "Action_name: $action_name, Action_input: $action_input, Observation: $observation"
|
||||
str = "actionname: $actionname, actioninput: $actioninput, observation: $observation"
|
||||
d = Dict{Symbol, String}(:name=>subject, :text=>str)
|
||||
push!(log, d)
|
||||
end
|
||||
|
||||
@@ -239,7 +239,9 @@ a = YiemAgent.sommelier(
|
||||
while true
|
||||
print("\nyour respond: ")
|
||||
user_answer = readline()
|
||||
response = YiemAgent.conversation(a, Dict(:text=> user_answer))
|
||||
response = YiemAgent.conversation(agent;
|
||||
userinput=Dict(:text=> user_answer),
|
||||
maximumMsg=50)
|
||||
println("\n$response")
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user