This commit is contained in:
2023-11-23 10:08:41 +00:00
parent dc17f6d2a3
commit 39b94bb19f
2 changed files with 132 additions and 89 deletions

View File

@@ -4,7 +4,7 @@ module interface
export agentReact, agentReflex,
addNewMessage, clearMessage, removeLatestMsg, generatePrompt_tokenPrefix,
generatePrompt_tokenSuffix, conversation, work, detectCharacters, chunktext,
findDetectedCharacter, wikisearch
findDetectedCharacter, wikisearch, sendReceivePrompt
using JSON3, DataStructures, Dates, UUIDs, HTTP
using CommUtils, GeneralUtils
@@ -161,7 +161,7 @@ function generatePrompt_mistral_openorca(a::T, usermsg::String,
{tools}
{thinkingMode}
<|im_end|>
Here are the context for the question:
Here are the context for the assignment:
{context}
"""
prompt = replace(prompt, "{systemMsg}" => a.roles[a.role])
@@ -177,13 +177,13 @@ function generatePrompt_mistral_openorca(a::T, usermsg::String,
prompt = replace(prompt, "{context}" => a.context)
prompt *= "<|im_start|>user\nQuestion: " * usermsg * "\n<|im_end|>\n"
prompt *= "<|im_start|>user\nAssignment: " * usermsg * "\n<|im_end|>\n"
prompt *= "<|im_start|>assistant\n"
return prompt
end
function genPrompt_mistral_openorca(a::agentReflex, usermsg::String)
function chat_mistral_openorca(a::agentReflex, usermsg::String)
"""
general prompt format:
@@ -205,7 +205,7 @@ function genPrompt_mistral_openorca(a::agentReflex, usermsg::String)
{context} =
"
{earlierConversation}
{current status}
{env status}
{shortterm memory}
{longterm memory}
"
@@ -240,13 +240,13 @@ function genPrompt_mistral_openorca(a::agentReflex, usermsg::String)
prompt = replace(prompt, "{context}" => context)
prompt = replace(prompt, "{usermsg}" => "Request: $usermsg")
prompt = replace(prompt, "{usermsg}" => "Assignment: $usermsg")
return prompt
end
#WORKING
function genPrompt_planning_mistral_openorca(a::agentReflex, usermsg::String)
function planner_mistral_openorca(a::agentReflex, usermsg::String)
"""
general prompt format:
@@ -268,7 +268,7 @@ function genPrompt_planning_mistral_openorca(a::agentReflex, usermsg::String)
{context} =
"
{earlierConversation}
{current status}
{env status}
{shortterm memory}
{longterm memory}
"
@@ -289,7 +289,7 @@ function genPrompt_planning_mistral_openorca(a::agentReflex, usermsg::String)
"""
prompt = replace(prompt, "{role}" => a.roles[a.role])
prompt = replace(prompt, "{thinkingFormat}" => a.thinkingFormat[:plan])
prompt = replace(prompt, "{thinkingFormat}" => a.thinkingFormat[:planner])
toolnames = ""
toollines = ""
for (toolname, v) in a.tools
@@ -312,7 +312,7 @@ function genPrompt_planning_mistral_openorca(a::agentReflex, usermsg::String)
prompt = replace(prompt, "{context}" => context)
prompt = replace(prompt, "{usermsg}" => "Request: $usermsg")
prompt = replace(prompt, "{usermsg}" => "Assignment: $usermsg")
return prompt
end
@@ -435,7 +435,7 @@ function work(a::T, prompt::String, maxround::Int=3) where {T<:agent}
AnswerInd = length(Answer) != 0 ? Answer[1] : nothing
Act = findDetectedCharacter(headers, "Act $(a.thinkinground):")
if length(Answer) == 1 && length(Act) == 0
a.thought = "nothing" # question finished, no more thought
a.thought = "nothing" # assignment finished, no more thought
a.context = "nothing"
a.thinkinground = 0
respond = chunkedtext[AnswerInd][:body]
@@ -516,7 +516,7 @@ function conversation(a::agentReflex, usermsg::String; thinkingroundlimit::Int=3
if a.thinkingmode == :no_thinking
a.earlierConversation = conversationSummary(a) #TODO should be long conversation before use summary because it leaves out details
_ = addNewMessage(a, "user", usermsg)
prompt = genPrompt_mistral_openorca(a, usermsg) #TODO rewrite this function
prompt = chat_mistral_openorca(a, usermsg) #TODO rewrite this function
@show prompt
respond = sendReceivePrompt(a, prompt)
respond = split(respond, "<|im_end|>")[1]
@@ -532,35 +532,43 @@ end
#WORKING
function work(a::agentReflex, usermsg::String)
if a.thinkingmode == :new_thinking
a.earlierConversation = conversationSummary(a)
_ = addNewMessage(a, "user", usermsg)
elseif a.thinkingmode == :continue_thinking
_ = addNewMessage(a, "user", usermsg)
a.thought *= "Obs $(a.thinkinground): $usermsg\n"
a.thought *= "Obs $(a.attempt): $usermsg\n"
else
error("undefined condition thinkingmode = $thinkingmode")
end
while true
# plan
a.thinkinground += 1
@show a.thinkinground
a.attempt += 1
@show a.attempt
toolname = nothing
toolinput = nothing
prompt = genPrompt_planning_mistral_openorca(a, usermsg)
prompt = planner_mistral_openorca(a, usermsg)
@show prompt
respond = sendReceivePrompt(a, prompt)
respond = split(respond, "<|im_end|>")[1]
plan = split(respond, "<|im_end|>")[1]
@show respond
for
# execute
step = 0
while true
step += 1
isstep, stepdetail = extractStepFromPlan(a, plan, step)
@show isstep
@show stepdetail
if isstep
error("work done")
end
# evaluate
error("work done")
end
end
@@ -685,11 +693,11 @@ function chooseThinkingMode(a::T, usermsg::String) where {T<:agent}
{systemMsg}
You have access to the following tools:
{tools}
Your need to determine now whether you will use tools or actions to answer the question.
Your need to determine now whether you will use tools or actions to answer the assignment.
You have the following choices:
If you already know the answer or don't need tools or actions say, "{no}".
If you need tools or actions to answer the question say, "{yes}".
If you don't need tools or actions to fininsh the assignment say, "{no}".
If you need tools or actions to finish the assignment say, "{yes}".
<|im_end|>
<|im_start|>user
@@ -718,7 +726,7 @@ end
function chooseThinkingMode(a::agentReflex, usermsg::String)
thinkingmode = nothing
if a.thought != "nothing"
if a.thoughtlog != "nothing"
thinkingmode = :continue_thinking
else
prompt =
@@ -727,11 +735,11 @@ function chooseThinkingMode(a::agentReflex, usermsg::String)
{systemMsg}
You have access to the following tools:
{tools}
Your need to determine now whether you will use tools or actions to answer the question.
Your job is to determine whether you will use tools or actions to finish the assignment.
You have the following choices:
If you already know the answer or don't need tools or actions say, "{no}".
If you need tools or actions to answer the question say, "{yes}".
Choose one of the following choices:
If you don't need tools or actions to fininsh the assignment say, "{no}".
If you need tools or actions to finish the assignment say, "{yes}".
<|im_end|>
<|im_start|>user
@@ -758,34 +766,34 @@ function chooseThinkingMode(a::agentReflex, usermsg::String)
return thinkingmode
end
function identifyUserIntention(a::T, usermsg::String) where {T<:agent}
prompt =
"""
<|im_start|>system
You are a helpful assistant. Your job is to determine intention of the question.
# function identifyUserIntention(a::T, usermsg::String) where {T<:agent}
# prompt =
# """
# <|im_start|>system
# You are a helpful assistant. Your job is to determine intention of the question.
You have the following choices:
If the user question is about general conversation say, "{chat}".
If the user question is about getting wine say, "{wine}".
<|im_end|>
# You have the following choices:
# If the user question is about general conversation say, "{chat}".
# If the user question is about getting wine say, "{wine}".
# <|im_end|>
Here are the context for the question:
{context}
# Here are the context for the question:
# {context}
<|im_start|>user
{input}
<|im_end|>
<|im_start|>assistant
# <|im_start|>user
# {input}
# <|im_end|>
# <|im_start|>assistant
"""
prompt = replace(prompt, "{context}" => "")
prompt = replace(prompt, "{input}" => usermsg)
# """
# prompt = replace(prompt, "{context}" => "")
# prompt = replace(prompt, "{input}" => usermsg)
result = sendReceivePrompt(a, prompt)
answer = result === nothing ? nothing : GeneralUtils.getStringBetweenCharacters(result, "{", "}")
# result = sendReceivePrompt(a, prompt)
# answer = result === nothing ? nothing : GeneralUtils.getStringBetweenCharacters(result, "{", "}")
return answer
end
# return answer
# end
"""
Send a msg to registered mqtt topic within mqttClient.
@@ -851,7 +859,7 @@ function sendReceivePrompt(a::T, prompt::String; timeout::Int=120) where {T<:age
result = nothing
break
else
error("undefined condition $(@__LINE__)")
error("undefined condition. timepass=$timepass timeout=$timeout $(@__LINE__)")
end
end
@@ -892,25 +900,6 @@ function toolNameBeingCalled(text::T, tools::Dict) where {T<:AbstractString}
return toolNameBeingCalled
end
function answerNow(a::T) where {T<:agent}
prompt =
"""
<|im_start|>system
{systemMsg}
Your need to determine now whether you will use tools or actions to answer the question.
You have the following choices:
If you don't need tools or actions to answer the question say, "{no}".
If you need tools or actions to answer the question say, "{yes}".
<|im_end|>
"""
prompt = replace(prompt, "{systemMsg}" => a.thought)
error("answerNow done")
end
#TODO
function checkReasonableness(userMsg::String, context::String, tools)
# Ref: https://www.youtube.com/watch?v=XV4IBaZqbps
@@ -918,18 +907,18 @@ function checkReasonableness(userMsg::String, context::String, tools)
prompt =
"""
<|im_start|>system
You are a helpful assistant. Your job is to check the reasonableness of user questions.
If the user question can be answered given the tools available say, "This is a reasonable question".
If the user question cannot be answered then provide some feedback to the user that may improve
their question.
You are a helpful assistant. Your job is to check the reasonableness of user assignments.
If the user assignment can be answered given the tools available say, "This is a reasonable assignment".
If the user assignment cannot be answered then provide some feedback to the user that may improve
their assignment.
Here is the context for the question:
Here is the context for the assignment:
{context}
<|im_end|>
<|im_start|>user
{question}
{assignment}
<|im_end|>
<|im_start|>assistant
@@ -937,7 +926,7 @@ function checkReasonableness(userMsg::String, context::String, tools)
context = "You have access to the following tools:
WineStock: useful for when you need to find info about wine by matching your description, price, name or ID. Input should be a search query with as much details as possible."
prompt = replace(prompt, "{question}" => userMsg)
prompt = replace(prompt, "{assignment}" => userMsg)
prompt = replace(prompt, "{context}" => context)
output_py = llm(
@@ -1044,6 +1033,60 @@ function chunktext(text::T, headers) where {T<:AbstractString}
end
function extractStepFromPlan(a::agent, plan::T, stepToExtract::Int) where {T<:AbstractString}
prompt =
"""
<|im_start|>system
You are a helpful assistant.
Your job is to determine whether step {$stepToExtract} is in the user plan.
Choose one of the following choices:
If there isn't say, {no}.
If there is say, {yes}. {copy the step and put it here}
<|im_end|>
<|im_start|>user
$plan
<|im_end|>
<|im_start|>assistant
"""
isStep = nothing
step = nothing
respond = sendReceivePrompt(a, prompt)
isStep = GeneralUtils.getStringBetweenCharacters(respond, "{", "}")
if isStep == "no"
isStep = false
step = "nothing"
elseif isStep == "yes"
isStep = true
step = split(respond, "{yes}")[end]
else
error("undefined condition. isStep=$isStep $(@__LINE__)")
end
return isStep, step
end