From 804ec35da647f187dde98bf8e5f627a3c9346f10 Mon Sep 17 00:00:00 2001 From: tonaerospace Date: Fri, 8 Dec 2023 12:50:34 +0000 Subject: [PATCH] update --- src/interface.jl | 158 ++--------------------------------------------- src/type.jl | 10 ++- src/utils.jl | 96 +++++++++++++++++++++++++++- 3 files changed, 108 insertions(+), 156 deletions(-) diff --git a/src/interface.jl b/src/interface.jl index 30674a7..6dbceee 100755 --- a/src/interface.jl +++ b/src/interface.jl @@ -448,157 +448,6 @@ end julia> respond = ChatAgent.conversation(newAgent, "Hi! how are you?") ``` """ -function conversation(a::T, usermsg::String) where {T<:agent} - respond = nothing - - if a.thought != "nothing" # continue thought - _ = addNewMessage(a, "user", usermsg) - a.thought *= "Obs $(a.thinkinground): $usermsg\n" - prompt = a.thought - respond = work(a, prompt) - else # new thought - thinkingmode = chooseThinkingMode(a, usermsg) - @show thinkingmode - if thinkingmode == :no_thinking - a.context = conversationSummary(a) - _ = addNewMessage(a, "user", usermsg) - prompt = generatePrompt_mistral_openorca(a, usermsg, thinkingmode) - @show prompt - respond = sendReceivePrompt(a, prompt) - respond = split(respond, "<|im_end|>")[1] - respond = replace(respond, "\n" => "") - _ = addNewMessage(a, "assistant", respond) - @show respond - elseif thinkingmode == :thinking - a.context = conversationSummary(a) - _ = addNewMessage(a, "user", usermsg) - prompt = generatePrompt_mistral_openorca(a, usermsg, thinkingmode) - respond = work(a, prompt) - else - error("undefined condition thinkingmode = $thinkingmode $(@__LINE__)") - end - end - - return respond -end - -""" - Continuously run llm functions except when llm is getting Answer: or chatbox. - There are many work() depend on thinking mode. -""" -function work(a::T, prompt::String, maxround::Int=3) where {T<:agent} - respond = nothing - while true - a.thinkinground += 1 - @show a.thinkinground - toolname = nothing - toolinput = nothing - - if a.thinkinground > a.thinkingroundlimit - a.thought *= "Thought $(a.thinkinground): I think I know the answer." - prompt = a.thought - end - - @show prompt - respond = sendReceivePrompt(a, prompt) - - headerToDetect = nothing - if a.thinkinground == 1 - try - respond = split(respond, "Obs:")[1] - headerToDetect = ["Question:", "Plan:", "Thought:", "Act:", "Actinput:", "Obs:", "...", "Answer:", - "Conclusion:", "Summary:"] - catch - end - else - try - respond = split(respond, "Obs $(a.thinkinground):")[1] - headerToDetect = ["Question $(a.thinkinground):", "Plan $(a.thinkinground):", - "Thought $(a.thinkinground):", "Act $(a.thinkinground):", - "Actinput $(a.thinkinground):", "Obs $(a.thinkinground):", - "...", "Answer:", - "Conclusion:", "Summary:"] - catch - end - end - @show respond - headers = detectCharacters(respond, headerToDetect) - chunkedtext = chunktext(respond, headers) - - Answer = findDetectedCharacter(headers, "Answer:") - AnswerInd = length(Answer) != 0 ? Answer[1] : nothing - Act = findDetectedCharacter(headers, "Act $(a.thinkinground):") - if length(Answer) == 1 && length(Act) == 0 - a.thought = "nothing" # assignment finished, no more thought - a.context = "nothing" - a.thinkinground = 0 - respond = chunkedtext[AnswerInd][:body] - respond = replace(respond, "<|im_end|>"=>"") - _ = addNewMessage(a, "assistant", respond) - break - else - - # check for tool being called - ActHeader = a.thinkinground == 1 ? "Act:" : "Act $(a.thinkinground):" - if length(findDetectedCharacter(headers, ActHeader)) != 0 # check whether there is Act: in a respond - ActInd = findDetectedCharacter(headers, ActHeader)[1] - toolname = toolNameBeingCalled(chunkedtext[ActInd][:body], a.tools) - end - ActinputHeader = a.thinkinground == 1 ? "Actinput:" : "Actinput $(a.thinkinground):" - if length(findDetectedCharacter(headers, ActinputHeader)) != 0 # check whether there is Actinput: in a respond - ActinputInd = findDetectedCharacter(headers, ActinputHeader)[1] - toolinput = chunkedtext[ActinputInd][:body] - end - - # clean up - if occursin(" \"", toolinput) - toolinput = GeneralUtils.getStringBetweenCharacters(toolinput, " \"", "\"\n") - else - toolinput = GeneralUtils.getStringBetweenCharacters(toolinput, " ", "\n") - end - @show toolname - @show toolinput - if toolname === nothing || toolinput === nothing - println("toolname $toolname toolinput $toolinput retry thinking") - a.thinkinground -= 1 - continue - end - - if a.thought == "nothing" - thought = "" - for i in chunkedtext - header = i[:header] - header = replace(header, ":"=>" $(a.thinkinground):") # add number so that llm not confused - body = i[:body] - thought *= "$header $body" - end - a.thought = prompt * thought - else - a.thought *= respond - end - - - if toolname == "chatbox" # chat with user - a.thought *= toolinput - respond = toolinput - _ = addNewMessage(a, "assistant", respond) - break - else # function call - f = a.tools[Symbol(toolname)][:func] - _result = f(toolinput) - if _result != "No info available." #TODO for use with wikisearch(). Not good for other tools - _result = makeSummary(a, _result) - end - result = "Obs $(a.thinkinground): $_result\n" - a.thought *= result - prompt = a.thought - end - end - end - @show respond - return respond -end - function conversation(a::agentReflex, usermsg::String; attemptlimit::Int=3) a.attemptlimit = attemptlimit respond = nothing @@ -627,7 +476,10 @@ function conversation(a::agentReflex, usermsg::String; attemptlimit::Int=3) return respond end - +""" + Continuously run llm functions except when llm is getting Answer: or chatbox. + There are many work() depend on thinking mode. +""" function work(a::agentReflex, usermsg::String) respond = nothing @@ -856,6 +708,8 @@ function actor(a::agentReflex) msgToUser = toolinput actorState = toolname break + elseif toolname == "skipstep" + # skip else # function call f = a.tools[Symbol(toolname)][:func] toolresult = f(a, toolinput) diff --git a/src/type.jl b/src/type.jl index 428fceb..47bd076 100644 --- a/src/type.jl +++ b/src/type.jl @@ -107,7 +107,15 @@ function agentReflex( p.s.1 each step should be a single action. p.s.2 don't respond to the stimulus yet. """, - :actor=> + :actor=> + """ + Use the following format: + Thought: you should always think about do you have all the required info and what to do according to step {step} of the plan and the info you have (pay attention to correct numeral calculation and commonsense). + Act: the action to take that match your thought, should be one of [{toolnames}] + Actinput: your input to the action you chose (pay attention to the tool's input) + Obs: the result of the action + """, + :actorOriginal=> """ Use the following format: Thought: you should always think about do you have all the required info and what to do according to step {step} of the plan and the info you have (pay attention to correct numeral calculation and commonsense). diff --git a/src/utils.jl b/src/utils.jl index c59f499..21a926a 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -357,9 +357,8 @@ function chooseThinkingMode(a::agentReflex, usermsg::String) Your job is to determine whether you will use tools or actions to respond. Choose one of the following choices: - If you don't need to use tools or actions to respond to the stimulus say, "{no}". - If you need tools or actions to respond to the stimulus say, "{yes}". - If the user want to get wine say, "{yes}". + Choice 1: If the user want to get wine say, "{yes}". + Choice 2: If you don't need to use tools or actions to respond to the stimulus say, "{no}". <|im_end|> <|im_start|>user @@ -387,6 +386,97 @@ function chooseThinkingMode(a::agentReflex, usermsg::String) end +# function chooseThinkingMode(a::agentReflex, usermsg::String) +# thinkingmode = nothing +# if length(a.memory[:log]) != 0 +# thinkingmode = :continue_thinking +# else +# prompt = +# """ +# <|im_start|>system +# {systemMsg} +# You always use tools if there is a chance to impove your respond. +# You have access to the following tools: +# {tools} +# Your job is to determine whether you will use tools or actions to respond. + +# Choose one of the following choices: +# Choice 1: If you don't need to use tools or actions to respond to the stimulus say, "{no}". +# Choice 2: If you think the user want to get wine say, "{yes}". +# <|im_end|> + +# <|im_start|>user +# {input} +# <|im_end|> +# <|im_start|>assistant + +# """ +# toollines = "" +# for (toolname, v) in a.tools +# if toolname ∉ ["chatbox", "nothing"] +# toolline = "$toolname: $(v[:description]) $(v[:input]) $(v[:output])\n" +# toollines *= toolline +# end +# end +# prompt = replace(prompt, "{systemMsg}" => a.roles[a.role]) +# prompt = replace(prompt, "{tools}" => toollines) +# prompt = replace(prompt, "{input}" => usermsg) +# result = sendReceivePrompt(a, prompt) +# willusetools = GeneralUtils.getStringBetweenCharacters(result, "{", "}") +# thinkingmode = willusetools == "yes" ? :new_thinking : :no_thinking +# end + +# return thinkingmode +# end + +function chooseThinkingMode(a::agentReflex, usermsg::String) + thinkingmode = nothing + if length(a.memory[:log]) != 0 + thinkingmode = :continue_thinking + else + prompt = + """ + <|im_start|>system + {systemMsg} + You always use tools if there is a chance to impove your respond. + You have access to the following tools: + {tools} + + User message: + {input} + + Your job is to determine the following topics: + Topic 1: Is the user message show that they would like to get some wine? {Yes/No} + Topic 2: Is the user message show that they would like to get some cloth? {Yes/No} + <|im_end|> + <|im_start|>assistant + + """ + toollines = "" + for (toolname, v) in a.tools + if toolname ∉ ["chatbox", "nothing"] + toolline = "$toolname: $(v[:description]) $(v[:input]) $(v[:output])\n" + toollines *= toolline + end + end + prompt = replace(prompt, "{systemMsg}" => a.roles[a.role]) + prompt = replace(prompt, "{tools}" => toollines) + prompt = replace(prompt, "{input}" => usermsg) + result = sendReceivePrompt(a, prompt) + headers = detectCharacters(lessonwithcontext, ["Topic 1:", "Topic 2:"]) + chunkedtext = chunktext(result, headers) + @show chunkedtext + error(11) + willusetools = GeneralUtils.getStringBetweenCharacters(result, "{", "}") + thinkingmode = willusetools == "Yes" ? :new_thinking : :no_thinking + end + + @show result + error(11) + + return thinkingmode +end +