From be92ec2521cd39c93872128202894eeb49804ec4 Mon Sep 17 00:00:00 2001 From: tonaerospace Date: Sat, 16 Dec 2023 14:58:59 +0000 Subject: [PATCH] update --- src/interface.jl | 291 +++++++++++++++++++++++++++-------------------- src/utils.jl | 4 + 2 files changed, 170 insertions(+), 125 deletions(-) diff --git a/src/interface.jl b/src/interface.jl index 47879ff..840cf0c 100755 --- a/src/interface.jl +++ b/src/interface.jl @@ -291,6 +291,8 @@ function planner_mistral_openorca(a::agentReflex) Use the following format: Objective: the objective you intend to do Plan: first you should always think about the objective, the info you need and the info you have thoroughly then extract and devise a complete, step by step plan (pay attention to correct numeral calculation and commonsense). + p.s.1 each step of the plan should be a single action. + p.s.2 it is better to ask all you need to know and then search your inventory. <|im_end|> $conversation <|im_start|>assistant @@ -426,7 +428,6 @@ function actor_mistral_openorca(a::agentReflex) " """ - mark = "$(a.step)" prompt = """ @@ -1000,62 +1001,69 @@ function actor(a::agentReflex) @show a.step if a.step < totalsteps -1 # the last step of the plan is responding, let work() do this part - prompt_actor = actor_mistral_openorca(a) + #WORKING check whether LLM already complete the current step + iscomplete = checkStepCompletion(a) - println("") - @show prompt_actor + if iscomplete == false + prompt_actor = actor_mistral_openorca(a) - response = sendReceivePrompt(a, prompt_actor) - response = splittext(response, ["Obs", "<|im_end|>"]) + println("") + @show prompt_actor - if !occursin("Thought", response) - response = "Thought: " * response - end + response = sendReceivePrompt(a, prompt_actor) + response = splittext(response, ["Obs", "<|im_end|>"]) - headerToDetect = ["Question:", "Plan:", "Thought:", - "Act:", "Actinput:", "Obs:", "...", - "Answer:", "Conclusion:", "Summary:"] - - # replace headers with headers with correct attempt and step number - response = replaceHeaders(response, headerToDetect, a.step) - - headers = detectCharacters(response, headerToDetect) + if !occursin("Thought", response) + response = "Thought: " * response + end - println("") - response_actor = response - @show response_actor + headerToDetect = ["Question:", "Plan:", "Thought:", + "Act:", "Actinput:", "Obs:", "...", + "Answer:", "Conclusion:", "Summary:"] + + # replace headers with headers with correct attempt and step number + response = replaceHeaders(response, headerToDetect, a.step) + + headers = detectCharacters(response, headerToDetect) - headerToDetect = ["Plan $(a.attempt):", - "Thought $(a.step):", - "Act $(a.step):", - "Actinput $(a.step):", - "Obs $(a.step):", - "Check $(a.step):",] - headers = detectCharacters(response, headerToDetect) - chunkedtext = chunktext(response, headers) + println("") + response_actor = response + @show response_actor + + headerToDetect = ["Plan $(a.attempt):", + "Thought $(a.step):", + "Act $(a.step):", + "Actinput $(a.step):", + "Obs $(a.step):", + "Check $(a.step):",] + headers = detectCharacters(response, headerToDetect) + chunkedtext = chunktext(response, headers) - # add to memory - a.memory[:shortterm] = addShortMem!(a.memory[:shortterm], chunkedtext) - a.memory[:log] = addShortMem!(a.memory[:log], chunkedtext) + # add to memory + a.memory[:shortterm] = addShortMem!(a.memory[:shortterm], chunkedtext) + a.memory[:log] = addShortMem!(a.memory[:log], chunkedtext) - toolname = toolNameBeingCalled(chunkedtext["Act $(a.step):"], a.tools) - toolinput = chunkedtext["Actinput $(a.step):"] - @show toolname - @show toolinput + toolname = toolNameBeingCalled(chunkedtext["Act $(a.step):"], a.tools) + toolinput = chunkedtext["Actinput $(a.step):"] + @show toolname + @show toolinput - if toolname == "chatbox" # chat with user - msgToUser = toolinput - actorState = toolname - break - elseif toolname == "skipstep" - a.step += 1 - else # function call - f = a.tools[toolname][:func] - toolresult = f(a, toolinput) - @show toolresult - a.memory[:shortterm]["Obs $(a.step):"] = toolresult - a.memory[:log]["Obs $(a.step):"] = toolresult + if toolname == "chatbox" # chat with user + msgToUser = toolinput + actorState = toolname + break + elseif toolname == "skipstep" + a.step += 1 + else # function call + f = a.tools[toolname][:func] + toolresult = f(a, toolinput) + @show toolresult + a.memory[:shortterm]["Obs $(a.step):"] = toolresult + a.memory[:log]["Obs $(a.step):"] = toolresult + end + else + # already complete this step, go to the next step end else actorState = "all steps done" @@ -1339,84 +1347,6 @@ function formulateUserresponse(a) end - -""" Determine whether LLM should go to next step. - -Arguments: - a, one of ChatAgent's agent. - -Return: - "Yes" or "no" decision to go next step. - -# Example -```jldoctest -julia> using ChatAgent, CommUtils -julia> agent = ChatAgent.agentReflex("Jene") -julia> shorttermMemory = OrderedDict{String, Any}( - "user:" => "What's the latest AMD GPU?", - "Plan 1:" => " To answer this question, I will need to search for the latest AMD GPU using the wikisearch tool.\n", - "Act 1:" => " wikisearch\n", - "Actinput 1:" => " amd gpu latest\n", - "Obs 1:" => "No info available for your search query.", - "Act 2:" => " wikisearch\n", - "Actinput 2:" => " amd graphics card latest\n", - "Obs 2:" => "No info available for your search query.") - -julia> decision = goNogo(agent) -"Yes" -``` -""" -function goNogo(a) - # stimulus = a.memory[:shortterm]["user:"] - work = dictToString(a.memory[:shortterm]) - - prompt = - """ - <|im_start|>system - Symbol meaning: - Stimulus: the input user gives to you and you must response - Plan: a plan - Thought: your thought - Act: the action you took - Actinput: the input to the action - Obs: the result of the action - - Your work: - $work - - Your job is to check whether step $(a.step) of your work is completed according to the plan and choose only one of the following choices. - choice 1: If you get what you intend to do and you are ready to do the next step of the plan say, "{Yes}". And what is the rationale behind the decision to do the next step? - choice 2: If you didn't get what you intend to do and you need to repeat the latest step say, "{No}". And what is the rationale behind the decision to repeat the latest step? - <|im_end|> - <|im_start|>assistant - - """ - - response = sendReceivePrompt(a, prompt) - decision = nothing - reason = nothing - if occursin("Yes", response) - decision = "Yes" - elseif occursin("No", response) - decision = "No" - else - error("undefied condition, decision $decision $(@__LINE__)") - end - - startInd = findfirst(decision, response)[end] +2 - - if occursin(":", response[startInd:end]) # check for ":" after decision cha - startInd2 = findnext(":", response, startInd)[end]+1 - reason = response[startInd2:end] - else - reason = response[startInd:end] - end - - return decision, reason -end - - - """ Extract important info from text into key-value pair text. Arguments: @@ -1509,7 +1439,118 @@ end +""" Determine whether LLM should go to next step. +Arguments: + a, one of ChatAgent's agent. + +Return: + "Yes" or "no" decision to go next step. + +# Example +```jldoctest +julia> using ChatAgent, CommUtils +julia> agent = ChatAgent.agentReflex("Jene") +julia> shorttermMemory = OrderedDict{String, Any}( + "user:" => "What's the latest AMD GPU?", + "Plan 1:" => " To answer this question, I will need to search for the latest AMD GPU using the wikisearch tool.\n", + "Act 1:" => " wikisearch\n", + "Actinput 1:" => " amd gpu latest\n", + "Obs 1:" => "No info available for your search query.", + "Act 2:" => " wikisearch\n", + "Actinput 2:" => " amd graphics card latest\n", + "Obs 2:" => "No info available for your search query.") + +julia> decision = goNogo(agent) +"Yes" +``` +""" +function goNogo(a) + # stimulus = a.memory[:shortterm]["user:"] + work = dictToString(a.memory[:shortterm]) + + prompt = + """ + <|im_start|>system + Symbol meaning: + Plan: a plan + Thought: your thought + Act: the action you took + Actinput: the input to the action + Obs: the result of the action + + Your work: + $work + + Your job is to check whether step $(a.step) of your work is completed according to the plan and choose only one of the following choices. + choice 1: If you get what you intend to do and you are ready to do the next step of the plan say, "{Yes}". And what is the rationale behind the decision to do the next step? + choice 2: If you didn't get what you intend to do and you need to repeat the latest step say, "{No}". And what is the rationale behind the decision to repeat the latest step? + <|im_end|> + <|im_start|>assistant + + """ + + response = sendReceivePrompt(a, prompt) + decision = nothing + reason = nothing + if occursin("Yes", response) + decision = "Yes" + elseif occursin("No", response) + decision = "No" + else + error("undefied condition, decision $decision $(@__LINE__)") + end + + startInd = findfirst(decision, response)[end] +2 + + if occursin(":", response[startInd:end]) # check for ":" after decision cha + startInd2 = findnext(":", response, startInd)[end]+1 + reason = response[startInd2:end] + else + reason = response[startInd:end] + end + + return decision, reason +end + + + +function checkStepCompletion(a::agentReflex) + result = false + #WORKING I need current step of the plan + plan = "Plan $(a.attempt):" + plan = a.memory[:shortterm][plan] + + prompt = + """ + <|im_start|>system + Symbol meaning: + Plan: a plan + Thought: your thought + Act: the action you took + Actinput: the input to the action + Obs: the result of the action + + Your plan: + $plan + + What is step $(a.step) of the plan? + <|im_end|> + <|im_start|>assistant + + """ + + response = sendReceivePrompt(a, prompt) + + response = split(response, "<|im_end|>")[1] + + # mistral 7B already know info example: 2. Determine the occasion (wedding party). + if occursin("(", response) && occursin(")", response) + result = true + end + + return result +end diff --git a/src/utils.jl b/src/utils.jl index cb4e9da..1b47fde 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -412,6 +412,10 @@ function isUseTools(a::agentReflex) end end + if length(a.memory[:shortterm]) != 0 + isusetool = true + end + return isusetool end