From efd01cb5250f7eff3e81c35faaf09250b630b2c2 Mon Sep 17 00:00:00 2001 From: tonaerospace Date: Sun, 26 Nov 2023 10:42:40 +0000 Subject: [PATCH] update --- src/interface.jl | 115 ++++++++++++++++++++++++++++----------------- src/llmfunction.jl | 4 +- src/utils.jl | 80 ++++++++++++++++--------------- 3 files changed, 115 insertions(+), 84 deletions(-) diff --git a/src/interface.jl b/src/interface.jl index 3e1f804..b65743f 100755 --- a/src/interface.jl +++ b/src/interface.jl @@ -588,7 +588,7 @@ function conversation(a::agentReflex, usermsg::String; attemptlimit::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 = chat_mistral_openorca(a, usermsg) #TODO rewrite this function + prompt = chat_mistral_openorca(a, usermsg) @show prompt respond = sendReceivePrompt(a, prompt) respond = split(respond, "<|im_end|>")[1] @@ -604,6 +604,8 @@ end function work(a::agentReflex, usermsg::String) + respond = nothing + if a.thinkingmode == :new_thinking a.earlierConversation = conversationSummary(a) _ = addNewMessage(a, "user", usermsg) @@ -618,44 +620,65 @@ function work(a::agentReflex, usermsg::String) while true # Work loop # plan a.attempt += 1 - if a.attempt <= a.attemptlimit - - else # attempt limit reached - - end @show a.attempt @show usermsg - logmsg = "user: $usermsg\n" - a.memory[:shortterm] *= logmsg + if a.attempt <= a.attemptlimit + logmsg = "user: $usermsg\n" + a.memory[:shortterm] *= logmsg - toolname = nothing - toolinput = nothing - prompt = planner_mistral_openorca(a, usermsg) - @show prompt - respond = sendReceivePrompt(a, prompt) - plan = split(respond, "<|im_end|>")[1] - plan = split(plan, "Response:")[1] - _plan = replace(plan, "Plan:"=>"Plan $(a.attempt):") - logmsg = "assistant: $_plan\n" - a.memory[:shortterm] *= logmsg - actorstate, msgToUser = actor(a, plan) - #WORKING - if actorstate == "chatbox" - return msgToUser - elseif actorstate == "all steps done" - error(">>>>>>>>>> ", a.memory[:shortterm]) - # evaluationGuideline = writeEvaluationGuideline(a, ) - break - else - error("undefied condition, actorstate $actorstate $(@__LINE__)") + toolname = nothing + toolinput = nothing + prompt = planner_mistral_openorca(a, usermsg) + @show prompt + respond = sendReceivePrompt(a, prompt) + plan = split(respond, "<|im_end|>")[1] + plan = split(plan, "Response:")[1] + _plan = replace(plan, "Plan:"=>"Plan $(a.attempt):") + logmsg = "assistant: $_plan\n" + a.memory[:shortterm] *= logmsg + actorstate, msgToUser = actor(a, plan) + + if actorstate == "chatbox" + respond = msgToUser + break + elseif actorstate == "all steps done" + println("all steps done") + #WORKING give answer to the question + respond = formulateRespond() + + #TODO evaluate. if score < 8/10 try again. + headerToDetect = ["user:", "assistant:", ] + headers = detectCharacters(a.memory[:shortterm], headerToDetect) + chunkedtext = chunktext(a.memory[:shortterm], headers) + stimulus = chunkedtext["user:"] + guideline = writeEvaluationGuideline(a, stimulus) + score = grading(a, guideline, a.memory[:shortterm]) + @show score + if score >= 8 # good enough answer + @show a.memory[:shortterm] + a.memory[:shortterm] = "" + a.thoughtlog = "" + respond = msgToUser + break + else # self evaluate and reflect then try again + report = analyze(a, a.memory[:shortterm]) + @show report + lesson = selfReflext(a, report) + @show lesson + error(">>>>>>>>>>") + end + else + error("undefied condition, actorstate $actorstate $(@__LINE__)") + break + end + else #TODO attempt limit reached, force AI to answer + error("attempt limit reach") break end - - - - - end + + # good enough answer + return respond end @@ -678,10 +701,11 @@ end """ function actor(a::agentReflex, plan::T) where {T<:AbstractString} actorState = nothing + msgToUser = nothing + @show plan totalsteps = checkTotalStepInPlan(a, plan) - msgToUser = nothing a.step = 0 while true # Actor loop a.step += 1 @@ -713,22 +737,21 @@ function actor(a::agentReflex, plan::T) where {T<:AbstractString} _ = addNewMessage(a, "assistant", respond) msgToUser = respond actorState = toolname - error("actor done 0") break else # function call f = a.tools[Symbol(toolname)][:func] - result = f(toolinput) - result = "\nObs $(a.step): $result\n" - a.memory[:shortterm] *= result + result = f(a, toolinput) + _result = "\nObs $(a.step): $result\n" + a.memory[:shortterm] *= _result + msgToUser = result end else #TODO finish all steps actorState = "all steps done" msgToUser = nothing - error("actor done 2") break end end - error("actor done 3") + return actorState, msgToUser end @@ -830,7 +853,10 @@ function grading(a, guideline::T, shorttermMemory::T) where {T<:AbstractString} """ respond = sendReceivePrompt(a, prompt) - score = parse(Int, respond[end-4:end-3]) + println("grading = ", respond) + _score = split(respond[end-5:end], "/")[1] + _score = split(_score, " ")[end] + score = parse(Int, _score) return score end @@ -941,8 +967,11 @@ function selfReflext(a, report::T) where {T<:AbstractString} end - - +""" +""" #WORKING +function formulateRespond(a, shorttermMemory::T) where {T<:AbstractString} + +end diff --git a/src/llmfunction.jl b/src/llmfunction.jl index 6651224..525edd0 100644 --- a/src/llmfunction.jl +++ b/src/llmfunction.jl @@ -4,7 +4,7 @@ export wikisearch using HTTP, JSON3 using GeneralUtils -using ..utils +using ..type, ..utils #------------------------------------------------------------------------------------------------100 """ @@ -21,7 +21,7 @@ using ..utils "Advanced Micro Devices, Inc., commonly abbreviated as AMD, is an ..." ``` """ -function wikisearch(phrase::T) where {T<:AbstractString} +function wikisearch(a::agentReflex, phrase::T) where {T<:AbstractString} phrase = phrase[1] == " " ? phrase[2:end] : phrase # prepare input phrase if occursin("\"", phrase) diff --git a/src/utils.jl b/src/utils.jl index 6a30386..a6dd42c 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -128,6 +128,47 @@ function sendReceivePrompt(a::T, prompt::String; timeout::Int=120) where {T<:age end + +""" + Detect given characters. Output is a list of named tuple of detected char. + + ```jldoctest + julia> text = "I like to eat apples and use utensils." + julia> characters = ["eat", "use", "i"] + julia> result = detectCharacters(text, characters) + 4-element Vector{Any}: + (char = "i", start = 4, stop = 4) + (char = "eat", start = 11, stop = 13) + (char = "use", start = 26, stop = 28) + (char = "i", start = 35, stop = 35) + ``` +""" +function detectCharacters(text::T1, characters::Vector{T2}) where {T1<:AbstractString, T2<:AbstractString} + result = [] + for i in eachindex(text) + for char in characters + l = length(char) + char_startInd = i + char_endInd = i+l-1 # -1 because Julia use inclusive index + + if char_endInd > length(text) + # skip + else + try # some time StringIndexError: invalid index [535], valid nearby indices [534]=>'é', [536]=>' ' + if text[char_startInd: char_endInd] == char + push!(result, (char=char, start=char_startInd, stop=char_endInd)) + end + catch + end + end + end + end + + return result +end + + + """ Chunk a text into smaller pieces by header. ```jldoctest @@ -212,45 +253,6 @@ function checkTotalStepInPlan(a::agent, plan::T) where {T<:AbstractString} end - -""" - Detect given characters. Output is a list of named tuple of detected char. - - ```jldoctest - julia> text = "I like to eat apples and use utensils." - julia> characters = ["eat", "use", "i"] - julia> result = detectCharacters(text, characters) - 4-element Vector{Any}: - (char = "i", start = 4, stop = 4) - (char = "eat", start = 11, stop = 13) - (char = "use", start = 26, stop = 28) - (char = "i", start = 35, stop = 35) - ``` -""" -function detectCharacters(text::T1, characters::Vector{T2}) where {T1<:AbstractString, T2<:AbstractString} - result = [] - for i in eachindex(text) - for char in characters - l = length(char) - char_startInd = i - char_endInd = i+l-1 # -1 because Julia use inclusive index - - if char_endInd > length(text) - # skip - else - try # some time StringIndexError: invalid index [535], valid nearby indices [534]=>'é', [536]=>' ' - if text[char_startInd: char_endInd] == char - push!(result, (char=char, start=char_startInd, stop=char_endInd)) - end - catch - end - end - end - end - - return result -end - """ Find a given character from a vector of named tuple. Output is character location index inside detectedCharacters