From 39b94bb19fa9c700a0c3547b312a38e7e2a36dcc Mon Sep 17 00:00:00 2001 From: tonaerospace Date: Thu, 23 Nov 2023 10:08:41 +0000 Subject: [PATCH] update --- src/interface.jl | 201 ++++++++++++++++++++++++++++------------------- src/type.jl | 20 ++--- 2 files changed, 132 insertions(+), 89 deletions(-) diff --git a/src/interface.jl b/src/interface.jl index 55c7b9c..7c425e3 100755 --- a/src/interface.jl +++ b/src/interface.jl @@ -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 + + + + + + + + + + + + + + + + + + + + diff --git a/src/type.jl b/src/type.jl index cd5e086..13ba5ad 100644 --- a/src/type.jl +++ b/src/type.jl @@ -34,8 +34,8 @@ abstract type agent end # messages= [Dict(:role=>"system", :content=> "", :timestamp=> Dates.now()),] messages = Vector{Dict{Symbol, Any}}() tools::Union{Dict, Nothing} = nothing - thought::String = "nothing" # logs unfinished thoughts - thinkinground::Int = 0 # no. of thinking round + thoughtlog::String = "nothing" # logs unfinished thoughts + attempt::Int = 0 # no. of attempt thinkingroundlimit::Int = 5 # thinking round limit thinkingmode::Symbol = :no_thinking thinkingFormat::Union{Dict, Nothing} = nothing @@ -52,7 +52,7 @@ function agentReflex( roles::Dict=Dict( :assistant => """ - You are a helpful assistant who answer the user's questions as best you can. + You are a helpful assistant who finish a user's assignment as best you can. """, :sommelier => """ @@ -83,16 +83,16 @@ function agentReflex( Answer: Answer of the original question Begin!""", - :plan=> + :planner=> """Use the following format: - Request: the input request your user is asking and you must respond - Plan: first you should always think about the request and the info you have thoroughly then extract and devise a step by step plan to respond (pay attention to correct numeral calculation and commonsense). + Assignment: the input assignment your user is assigning and you must finish + Plan: first you should always think about the assignment and the info you have thoroughly then extract and devise a step by step plan to finish (pay attention to correct numeral calculation and commonsense). """, - :qta=> + :worker=> """Use the following format: - Question: the input question your user is asking and you must answer - Thought: ask yourself do you have all the info you need? And what to do according to the plan (pay attention to correct numeral calculation and commonsense). - Act: the tool that match your thought, should be one of {toolnames} + Assignment: the input assignment your user is assigning and you must finish + Thought: your should always think about what to do (pay attention to correct numeral calculation and commonsense). + Act: the action to take that match your thought, should be one of {toolnames} ActInput: the input to the action (pay attention to the tool's input) Begin!""",