This commit is contained in:
2023-12-08 12:50:34 +00:00
parent 7442a9f63b
commit 804ec35da6
3 changed files with 108 additions and 156 deletions

View File

@@ -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)