From 859d42c9039e88254c2608a04a04399df8ba9cbd Mon Sep 17 00:00:00 2001 From: "youremail@yourdomain.com" Date: Thu, 21 Dec 2023 11:06:50 +0000 Subject: [PATCH] update --- src/interface.jl | 177 ++++++++++++++++++++++++++++++++++------------- src/type.jl | 2 +- src/utils.jl | 14 ++++ 3 files changed, 142 insertions(+), 51 deletions(-) diff --git a/src/interface.jl b/src/interface.jl index c59c106..cb3e950 100755 --- a/src/interface.jl +++ b/src/interface.jl @@ -431,7 +431,7 @@ function actor_mistral_openorca(a::agentReflex) if !occursin("Thought", response) response = "Thought $(a.step): " * response end - @show response_actor1 = response + headerToDetect = ["Question:", "Plan:", "Thought:", "Act:", "Actinput:", "Obs:", "...", "Answer:", "Conclusion:", "Summary:"] @@ -443,7 +443,7 @@ function actor_mistral_openorca(a::agentReflex) headers = detectCharacters(response, headerToDetect) println("") - @show response_actor2 = response + @show response_actor = response headerToDetect = ["Plan $(a.attempt):", "Thought $(a.step):", @@ -455,7 +455,10 @@ function actor_mistral_openorca(a::agentReflex) chunkedtext = chunktext(response, headers) # assuming length more than 10 character means LLM has valid thinking - if haskey(chunkedtext, "Thought $(a.step):") && haskey(chunkedtext, "Act $(a.step):") + @show iskey_Thought = haskey(chunkedtext, "Thought $(a.step):") + @show iskey_Act = haskey(chunkedtext, "Act $(a.step):") + @show iskey_Actinput = haskey(chunkedtext, "Actinput $(a.step):") + if iskey_Thought && iskey_Act && iskey_Actinput if length(chunkedtext["Thought $(a.step):"]) > 10 && length(chunkedtext["Act $(a.step):"]) > 10 break end @@ -466,29 +469,20 @@ function actor_mistral_openorca(a::agentReflex) toolinput = chunkedtext["Actinput $(a.step):"] # change trailing number to continue a.memory[:shortterm] - _latestStep = keys(a.memory[:shortterm]) - _latestStep = [i for i in _latestStep] - _latestStep = _latestStep[end] - latestStep = parse(Int, _latestStep[end-2:end-1]) headerToDetect = ["Question:", "Plan:", "Thought:", "Act:", "Actinput:", "Obs:", "...", "Answer:", "Conclusion:", "Summary:"] - nextstep = latestStep+1 # next step in short term memory - response = replaceHeaders(response, headerToDetect, nextstep) + response = replaceHeaders(response, headerToDetect, a.step) headerToDetect = ["Plan $(a.attempt):", - "Thought $nextstep:", - "Act $nextstep:", - "Actinput $nextstep:", - "Obs $nextstep:", - "Check $nextstep:",] + "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 - addShortMem!(a.memory[:shortterm], chunkedtext) - a.memory[:log] = addShortMem!(a.memory[:log], chunkedtext) - - return toolname, toolinput + return toolname, toolinput, chunkedtext end @@ -575,25 +569,25 @@ function work(a::agentReflex) end end end - + while true # Work loop objective = nothing - # plan - if a.attempt <= a.attemptlimit - toolname = nothing - toolinput = nothing - + # make new plan + if !haskey(a.memory[:shortterm], "Plan 1:") plan = planner_mistral_openorca(a) a.memory[:shortterm]["Plan $(a.attempt):"] = plan a.memory[:log]["Plan $(a.attempt):"] = plan a.step = 1 # reset because new plan is created - println("") @show plan - println("") @show a.attempt + end + + if a.attempt <= a.attemptlimit + toolname = nothing + toolinput = nothing # enter actor loop actorstate, msgToUser = actor(a) @@ -694,15 +688,20 @@ function actor(a::agentReflex) while true # Actor loop @show a.step # check whether the current step is completed - iscomplete, reason = checkStepCompletion(a) - @show stepcompletecheck = iscomplete + isstepcomplete, reason = checkStepCompletion(a) + @show stepcompletecheck = reason + chunkedtext = nothing - if !iscomplete # not yet done + if !haskey(a.memory[:shortterm], "Thought $(a.step):") # agent didn't do this step yet. # work - toolname, toolinput = actor_mistral_openorca(a) + toolname, toolinput, chunkedtext = actor_mistral_openorca(a) println("") @show toolname @show toolinput + println("") + @show a.step + addShortMem!(a.memory[:shortterm], chunkedtext) + println("") if toolname == "chatbox" # chat with user msgToUser = toolinput @@ -718,25 +717,99 @@ function actor(a::agentReflex) a.memory[:shortterm]["Obs $(a.step):"] = toolresult a.memory[:log]["Obs $(a.step):"] = toolresult end - else #WORKING already done - a.step +=1 - # if not add to memory yet. Add - - # step +1 - - #TODO may be let LLM call finalResponse() - # if a.step > totalsteps # the last step of the plan is responding, let work() do this part - # actorState = "all steps done" - # msgToUser = nothing - # break - # end - + elseif haskey(a.memory[:shortterm], "Thought $(a.step):") && isstepcomplete == false + a.memory[:shortterm] = removeHeaders(a.memory[:shortterm], a.step, ["Plan"]) + println("repeating step $(a.step)") + elseif haskey(a.memory[:shortterm], "Thought $(a.step):") && isstepcomplete == true + println(">>> step +1") + a.step += 1 + else + iskey = haskey(a.memory[:shortterm], "Thought $(a.step):") + error("undefined condition. Thought key=$iskey, isstepcomplete=$isstepcomplete $(@__LINE__)") end + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# if !iscomplete # not yet done +# +# # has Thought of current step means LLM already did this step +# if didthestep = true +# latestStep = shortMemLatestStep(a.memory[:shortterm]) +# a.memory[:shortterm] = removeHeaders(a.memory[:shortterm], latestStep, ["Plan"]) +# println("repeating step $(a.step)") +# end + +# # work +# toolname, toolinput, chunkedtext = actor_mistral_openorca(a) +# println("") +# @show toolname +# @show toolinput +# addShortMem!(a.memory[:shortterm], chunkedtext) + +# if toolname == "chatbox" # chat with user +# msgToUser = toolinput +# msgToUser = split(msgToUser, "\n\n")[1] +# actorState = toolname +# break +# elseif toolname == "noaction" +# 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 #WORKING already done +# a.step +=1 + + + +# #TODO may be let LLM call finalResponse() +# # if a.step > totalsteps # the last step of the plan is responding, let work() do this part +# # actorState = "all steps done" +# # msgToUser = nothing +# # break +# # end + +# end + + + + + # elseif decision == "No" # repeat the latest step # a.memory[:shortterm] = removeHeaders(a.memory[:shortterm], a.step, ["Plan"]) # a.memory[:log] = removeHeaders(a.memory[:log], a.step, ["Plan"]) @@ -1146,7 +1219,7 @@ julia> decision = checkStepCompletion(agent) function checkStepCompletion(a) # stimulus = a.memory[:shortterm]["user:"] work = dictToString(a.memory[:shortterm]) - #WORKING + prompt = """ <|system|> @@ -1159,7 +1232,6 @@ function checkStepCompletion(a) Your earlier work: $work - Your job is to check whether step $(a.step) of your work is completed according to the plan. So for instance the following: @@ -1174,9 +1246,14 @@ function checkStepCompletion(a) <|assistant|> """ - - response = sendReceivePrompt(a, prompt, max_tokens=512) - @show checkStepCompletion_response = response + response = nothing + while true + _response = sendReceivePrompt(a, prompt, max_tokens=512) + response = split(_response, "}")[1] * "}" + if occursin("{", response) + break + end + end decision = nothing if occursin("not done", response) @@ -1184,7 +1261,7 @@ function checkStepCompletion(a) elseif occursin("done", response) decision = true else - error("undefied condition, decision $decision $(@__LINE__)") + error("undefied condition, decision $_response $(@__LINE__)") end return decision, response diff --git a/src/type.jl b/src/type.jl index bb938ac..cd4ad95 100644 --- a/src/type.jl +++ b/src/type.jl @@ -167,7 +167,7 @@ function agentReflex( :actor=> """ Use the following format: - Thought: you should always think about what to do to achieve step {step} of the plan (pay attention to correct numeral calculation and commonsense). + Thought: do step {step} of the plan (pay attention to correct numeral calculation and commonsense). Act: the action to take that align with your thought, should be one of [{toolnames}] Actinput: your input to the action you chose (pay attention to the tool's input) Obs: observed result of the action diff --git a/src/utils.jl b/src/utils.jl index ea4547b..66ea2a5 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1015,7 +1015,21 @@ function experience(dict::T) where {T<:AbstractDict} return s end +""" Get the latest step number of short term memory +Arguments: + dict = a dictionary contain past experience + +Return: + latest step number + +# Example +```jldoctest +julia> dict = OrderedDict( + "Plan 1:" => "1. Ask about the type of food that will be served at the wedding party.") +julia>shortMemLatestStep(dict) +1 +""" function shortMemLatestStep(dict::T) where {T<:AbstractDict} _latest_step = keys(dict) _latest_step = [i for i in _latest_step]