update
This commit is contained in:
158
src/interface.jl
158
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)
|
||||
|
||||
10
src/type.jl
10
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).
|
||||
|
||||
96
src/utils.jl
96
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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user