From 9216f87ef840354cdf81f96ab3bc33bb1247ea26 Mon Sep 17 00:00:00 2001 From: tonaerospace Date: Tue, 5 Dec 2023 05:46:51 +0000 Subject: [PATCH] update --- src/interface.jl | 190 ++++++++++++++++++++++++++++++++++------------- src/type.jl | 4 +- 2 files changed, 140 insertions(+), 54 deletions(-) diff --git a/src/interface.jl b/src/interface.jl index f08a2b8..9383ef9 100755 --- a/src/interface.jl +++ b/src/interface.jl @@ -402,8 +402,7 @@ function actor_mistral_openorca(a::agentReflex) # context = replace(context, "{earlierConversation}" => "My earlier talk with the user:\n$(a.earlierConversation)") context = replace(context, "{env state}" => "") context = replace(context, "{longterm memory}" => "") - mark = "$(a.attempt)" - context = replace(context, "{plan}" => "My plan:\n$(a.memory[:shortterm]["Plan $mark:"])") + context = replace(context, "{plan}" => "My plan:\n$(a.memory[:shortterm]["Plan $(a.attempt):"])") prompt = replace(prompt, "{context}" => context) return prompt @@ -628,8 +627,6 @@ end function work(a::agentReflex, usermsg::String) respond = nothing - mark_plan = "$(a.attempt)" - mark_actor = "$(a.step)" if a.thinkingmode == :new_thinking a.earlierConversation = conversationSummary(a) @@ -637,13 +634,11 @@ function work(a::agentReflex, usermsg::String) a.memory[:shortterm]["user:"] = usermsg a.memory[:log]["user:"] = usermsg a.newplan = true - a.attempt = 1 elseif a.thinkingmode == :continue_thinking #TODO println("continue_thinking!!") _ = addNewMessage(a, "user", usermsg) - a.memory[:shortterm]["Obs $mark_actor:"] = usermsg - a.step += 1 - a.memory[:log]["Obs $mark_actor:"] = usermsg + a.memory[:shortterm]["Obs $(a.step):"] = usermsg + a.memory[:log]["Obs $(a.step):"] = usermsg else error("undefined condition thinkingmode = $thinkingmode $(@__LINE__)") end @@ -671,10 +666,11 @@ function work(a::agentReflex, usermsg::String) println("") @show plan - a.memory[:shortterm]["Plan $mark_plan:"] = plan - a.memory[:log]["Plan $mark_plan:"] = plan - a.step = 1 + a.attempt += 1 + a.step = 0 a.newplan = false + a.memory[:shortterm]["Plan $(a.attempt):"] = plan + a.memory[:log]["Plan $(a.attempt):"] = plan end # enter actor loop @@ -688,7 +684,7 @@ function work(a::agentReflex, usermsg::String) respond = formulateUserRespond(a) - a.memory[:shortterm]["Respond $mark_plan:"] = respond + a.memory[:shortterm]["Respond $(a.attempt):"] = respond a.memory[:log]["Respond $mark:"] = respond # evaluate. if score < 8/10 try again. @@ -725,7 +721,6 @@ function work(a::agentReflex, usermsg::String) error("attempt limit reach") break end - a.attempt += 1 end # good enough answer @@ -766,6 +761,30 @@ function actor(a::agentReflex) totalsteps = checkTotalStepInPlan(a) while true # Actor loop + #WORKING + if a.step == 0 + a.step = 1 + else + decision, reason = goNogo(a) + println("") + @show decision + @show reason + a.memory[:shortterm]["Check $(a.step):"] = reason + if decision == "Yes" # in case there is a cancel, go straight to evaluation + a.step += 1 + elseif decision == "No" + # repeat the latest step + # TODO delete Thought/Act/ActInput from the latest input + error("repete step $(a.step)") + elseif decision == "formulateUserRespond" + actorState = "formulateUserRespond" + msgToUser = nothing + break + else + error("undefined condition decision = $decision $(@__LINE__)") + end + end + @show a.step if a.step <= totalsteps @@ -795,14 +814,12 @@ function actor(a::agentReflex) println("") @show respond_actor - mark_plan = "$(a.attempt)" - mark_actor = "$(a.step)" - headerToDetect = ["Plan $mark_plan:", - "Thought $mark_actor:", - "Act $mark_actor:", - "ActInput $mark_actor:", - "Obs $mark_actor:", - "Check $mark_actor:",] + headerToDetect = ["Plan $(a.attempt):", + "Thought $(a.step):", + "Act $(a.step):", + "ActInput $(a.step):", + "Obs $(a.step):", + "Check $(a.step):",] headers = detectCharacters(respond, headerToDetect) chunkedtext = chunktext(respond, headers) @show chunkedtext @@ -810,34 +827,20 @@ function actor(a::agentReflex) # add to memory a.memory[:shortterm] = addShortMem!(a.memory[:shortterm], chunkedtext) - toolname = toolNameBeingCalled(chunkedtext["Act $mark_actor:"], a.tools) - toolinput = chunkedtext["ActInput $mark_actor:"] + toolname = toolNameBeingCalled(chunkedtext["Act $(a.step):"], a.tools) + toolinput = chunkedtext["ActInput $(a.step):"] @show toolname @show toolinput if toolname == "chatbox" # chat with user - #TODO donot use chatbox to respond to user - respond = toolinput - msgToUser = respond + msgToUser = toolinput actorState = toolname break - elseif toolname == "formulateUserRespond" - actorState = "formulateUserRespond" - break else # function call f = a.tools[Symbol(toolname)][:func] toolresult = f(a, toolinput) @show toolresult - a.memory[:shortterm]["Obs $mark_actor:"] = toolresult - a.step += 1 - - go, reason = goNogo(a) - @show go - a.memory[:shortterm]["Check $mark_actor:"] = reason - if go == "No" # in case there is a cancel, go straight to evaluation - a.step -= 1 - error(113) - end + a.memory[:shortterm]["Obs $(a.step):"] = toolresult end else #TODO finish all steps actorState = "all steps done" @@ -1086,7 +1089,7 @@ julia> shorttermMemory = OrderedDict{String, Any}( "ActInput 2:" => " amd graphics card latest\n", "Obs 2:" => "No info available for your search query.") -julia> report = formulateRespond(agent, shorttermMemory) +julia> report = formulateUserRespond(agent, shorttermMemory) ``` """ function formulateUserRespond(a) @@ -1160,15 +1163,34 @@ function goNogo(a) end end + # prompt = + # """ + # <|im_start|>system + # Symbol meaning: + # Stimulus: the input user gives to you and you must respond + # Plan: a plan + # Thought: your thought + # Act: the action you took + # ActInput: the input to the action + # Obs: the result of the action + + # Stimulus: + # $stimulus + + # Your work: + # $work + + # From your work, you job is to decide what to do next by choosing one of the following choices: + # If you are ready to do the next step of the plan say, "{Yes}". And what is the rationale behind the decision? + # If you need to repeat the latest step say, "{No}". And what is the rationale behind the decision? + # If you are ready to formulate a final respond to user original stimulus say, {formulateUserRespond}. And what is the rationale behind the decision? + # <|im_end|> + # """ prompt = """ <|im_start|>system - You have access to the following tools: - chatbox: Useful for when you need to ask a customer for more context. Input should be a conversation to customer. - wikisearch: Useful for when you need to search an encyclopedia Input is keywords and not a question. - - Symbol: + Symbol meaning: Stimulus: the input user gives to you and you must respond Plan: a plan Thought: your thought @@ -1182,20 +1204,84 @@ function goNogo(a) Your work: $work - From your work, you job is to decide whether you're ready to do the next step in the plan by choosing one of the following choices: - If you are ready say, "{Yes}". And what is the rationale behind the decision? - If you are not ready say, "{No}". And what is the rationale behind the decision? + From the latest step in your work, you job is to choose one of the following choices: + If you need to repeat the latest step say, "{No}". And what is the rationale behind the decision? + If you are ready to do the next step of the plan say, "{Yes}". And what is the rationale behind the decision? + If you are ready to formulate a final respond to user original stimulus say, {formulateUserRespond}. And what is the rationale behind the decision? <|im_end|> """ respond = sendReceivePrompt(a, prompt) - - decision = GeneralUtils.getStringBetweenCharacters(respond, "{", "}") - start = findfirst("}", respond)[end] +1 - reason = respond[start:end] + println("") + goNogo_raw = respond + @show goNogo_raw + + decision = nothing + reason = nothing + if occursin("Yes", respond) + decision = "Yes" + startInd = startInd = findfirst("Yes", respond)[end] +2 + reason = respond[startInd:end] + elseif occursin("No", respond) + decision = "No" + startInd = startInd = findfirst("No", respond)[end] +2 + reason = respond[startInd:end] + elseif occursin("formulateUserRespond", respond) + decision = "formulateUserRespond" + startInd = startInd = findfirst("formulateUserRespond", respond)[end] +2 + reason = respond[startInd:end] + else + end + + return decision, reason end +# function goNogo(a) +# stimulus = a.memory[:shortterm]["user:"] +# work = "" +# for (k, v) in a.memory[:shortterm] +# if k ∉ ["user:"] +# work *= "$k $v" +# end +# end + + +# prompt = +# """ +# <|im_start|>system +# You have access to the following tools: +# chatbox: Useful for when you need to ask a customer for more context. Input should be a conversation to customer. +# wikisearch: Useful for when you need to search an encyclopedia Input is keywords and not a question. + +# Symbol: +# Stimulus: the input user gives to you and you must respond +# Plan: a plan +# Thought: your thought +# Act: the action you took +# ActInput: the input to the action +# Obs: the result of the action + +# Stimulus: +# $stimulus + +# Your work: +# $work + +# From your work, you job is to decide whether you're ready to do the next step in the plan by choosing one of the following choices: +# If you are ready say, "{Yes}". And what is the rationale behind the decision? +# If you are not ready say, "{No}". And what is the rationale behind the decision? +# <|im_end|> +# """ + +# respond = sendReceivePrompt(a, prompt) + +# decision = GeneralUtils.getStringBetweenCharacters(respond, "{", "}") +# start = findfirst("}", respond)[end] +1 +# reason = respond[start:end] + +# return decision, reason +# end diff --git a/src/type.jl b/src/type.jl index ffd1691..9794425 100644 --- a/src/type.jl +++ b/src/type.jl @@ -36,8 +36,8 @@ abstract type agent end tools::Union{Dict, Nothing} = nothing newplan::Bool = false # if true, new plan will be generated attemptlimit::Int = 5 # thinking round limit - attempt::Int = 1 # attempted number - step::Int = 1 # step number + attempt::Int = 0 # attempted number + step::Int = 0 # step number thinkingmode::Symbol = :no_thinking thinkingFormat::Union{Dict, Nothing} = nothing memory::Dict = Dict(