This commit is contained in:
2023-11-19 00:46:22 +00:00
parent 955896e646
commit d016ba37cf

View File

@@ -60,6 +60,7 @@ abstract type agent end
context::String = "nothing" # internal thinking area
tools::Union{Dict, Nothing} = nothing
thought::String = "nothing" # contain unfinished thoughts for ReAct agent only
thoughtround::Int = 0
thinkingMode::Union{Dict, Nothing} = nothing
end
@@ -124,8 +125,8 @@ function agentReact(
:output => "" ,
:func => nothing,
),
:nothing=>Dict(
:name => "nothing",
:NTHING=>Dict(
:name => "NTHING",
:description => "useful for when you don't need to use tools or actions",
:input => "No input is needed",
:output => "" ,
@@ -315,7 +316,7 @@ function conversation(a::T, usermsg::String) where {T<:agent} #WORKING
if a.thought != "nothing" # continue thought
_ = addNewMessage(a, "user", usermsg)
a.thought *= "Obs: $usermsg\n"
a.thought *= "Obs $(a.thoughtround): $usermsg\n"
prompt = a.thought
respond = work(a, prompt)
else # new thought
@@ -350,40 +351,65 @@ end
function work(a::T, prompt::String) where {T<:agent}
respond = nothing
while true
a.thoughtround += 1
@show prompt
toolname = nothing
toolinput = nothing
respond = sendReceivePrompt(a, prompt)
@show respond
try
respond = split(respond, "Obs:")[1]
catch
headerToDetect = nothing
if a.thoughtround == 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.thoughtround):")[1]
headerToDetect = ["Question $(a.thoughtround):", "Plan $(a.thoughtround):",
"Thought $(a.thoughtround):", "Act $(a.thoughtround):",
"ActInput $(a.thoughtround):", "Obs $(a.thoughtround):",
"...", "Answer:",
"Conclusion:", "Summary:"]
catch
end
end
headers = detectCharacters(respond,
["Question:", "Plan:", "Thought:", "Act:", "ActInput:", "Obs:", "...", "Answer:",
"Conclusion:", "Summary:"])
headers = detectCharacters(respond, headerToDetect)
@show headers
chunkedtext = chunktext(respond, headers)
@show chunkedtext
if a.thought == "nothing"
a.thought = respond
else
thought = ""
for i in chunkedtext
header = i[:header]
header = replace(header, ":"=>" $(a.thoughtround):") # add number so that llm not confused
body = i[:body]
thought *= "$header $body"
end
a.thought = thought
else #WORKING make sure respond is numbered
a.thought *= respond
end
Answer = findDetectedCharacter(headers, "Answer:")
AnswerInd = length(Answer) != 0 ? Answer[1] : nothing
Act = findDetectedCharacter(headers, "Act:")
Act = findDetectedCharacter(headers, "Act $(a.thoughtround):")
if length(Answer) == 1 && length(Act) == 0
a.thought = "nothing" # question finished, no more thought
a.thoughtround = 0
respond = chunkedtext[AnswerInd][:body]
_ = addNewMessage(a, "assistant", respond)
break
else
# check for tool being called
ActInd = findDetectedCharacter(headers, "Act:")[1]
ActHeader = a.thoughtround == 1 ? "Act:" : "Act $(a.thoughtround):"
ActInd = findDetectedCharacter(headers, ActHeader)[1]
toolname = toolNameBeingCalled(chunkedtext[ActInd][:body], a.tools)
toolinput = chunkedtext[ActInd+1][:body]
if occursin(" \"", toolinput)
@@ -401,12 +427,13 @@ function work(a::T, prompt::String) where {T<:agent}
_ = addNewMessage(a, "assistant", respond)
break
else # function call
println("//////////// $(a.thoughtround)")
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: $_result\n"
result = "Obs $(a.thoughtround): $_result\n"
# result = "Obs: I found the following info. AMD is a semiconductor company making a CPU\n" #TESTING
@show result
a.thought *= result
@@ -805,14 +832,17 @@ end
"""
Chunk a text into smaller pieces by header.
```jldoctest
julia> using ChatAgent
julia> text = "Plan: First, we need to find out what kind of wine the user wants."
julia> headers = detectCharacters(text, ["Nope", "sick", "First", "user", "Then", ])
julia> headers = ChatAgent.detectCharacters(text, ["Nope", "sick", "First", "user", "Then", ])
3-element Vector{Any}:
(char = "First", start = 7, stop = 11)
(char = "user", start = 56, stop = 59)
(char = "Then", start = 102, stop = 105)
julia> chunkedtext = chunktext(text, headers)
julia> chunkedtext = ChatAgent.chunktext(text, headers)
2-element Vector{Any}:
(header = "First", body = ", we need to find out what kind of wine the ")
(header = "user", body = " wants.")
```
"""
function chunktext(text::T, headers) where {T<:AbstractString}