diff --git a/src/interface.jl b/src/interface.jl index 57cda40..28cff70 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -74,7 +74,7 @@ julia> output_thoughtDict = Dict( - [] implement RAG to pull similar experience - [] use customerinfo - [] user storeinfo - - [PENDING] add try block. check result that it is expected before returning + - [x] add try block. check result that it is expected before returning # Signature """ @@ -91,18 +91,23 @@ function decisionMaker(a::T1, state::T2)::Dict{Symbol, Any} where {T1<:agent, T2 $(JSON3.write(state[:storeinfo])) """ - reflect = "" - # """ - # You have attempted to answer the following question before and failed. The following - # reflection(s) give a plan to avoid failing to answer the question in the same way you did - # previously. Use them to improve your strategy of correctly answering the given question. - # (trajectories) - # """ + lesson = + if isempty(a.lesson) + "" + else + """ + You have attempted to answer the following question before and failed, either because your reasoning for the answer was incorrect or the phrasing of your response did not exactly match what the user want. The following lesson(s) give a plan to avoid failing to answer the question in the same way you did previously. Use them to improve your strategy of correctly answering the given question. + + $(JSON3.write(a.lesson[:lesson_1][:lesson])) + When providing the thought and action for the current trial, that into account these failed trajectories and make sure not to repeat the same mistakes and incorrect answers. + """ + end _prompt = """ You are a helpful sommelier working for a wine store. Your goal is to reccommend the best wine from your inventory that match the user preferences. + You are also an advanced reasoning agent that can improve based on self refection. You must follow the following criteria: 1) Get to know what occasion the user is buying wine for @@ -119,6 +124,7 @@ function decisionMaker(a::T1, state::T2)::Dict{Symbol, Any} where {T1<:agent, T2 1) winestock[query], which you can use to find wine in your inventory. The more input data the better. 2) chatbox[text], which you can use to interact with the user. 3) recommendbox[answer], which returns your wine reccommendation to the user. + After each observation, provide the next Thought and next Action. You should only respond in JSON format as describe below: { @@ -140,6 +146,8 @@ function decisionMaker(a::T1, state::T2)::Dict{Symbol, Any} where {T1<:agent, T2 "observation": "I'll take black." } + $lesson + Let's begin! $(JSON3.write(state[:thoughtHistory])) @@ -236,9 +244,6 @@ serving as a heuristic to steer the search algorithm towards the most promising julia> ``` -# TODO -- [PENDING] add try block. check result that it is expected before returning - # Signature """ function progressValueEstimator(a::T1, state::T2)::Tuple{String, Integer} where {T1<:agent, T2<:AbstractDict} @@ -325,7 +330,7 @@ function progressValueEstimator(a::T1, state::T2)::Tuple{String, Integer} where # check if dict has all required value dummya::AbstractString = evaluationDict[:evaluation] - dummyb::AbstractString = evaluationDict[:score] + dummyb::Integer = evaluationDict[:score] return (evaluationDict[:evaluation], evaluationDict[:score]) catch e @@ -339,7 +344,7 @@ function progressValueEstimator(a::T1, state::T2)::Tuple{String, Integer} where end if attempt > 5 - error("progressValueEstimator failed to generate a thought") + error("progressValueEstimator failed to generate an evaluation") end end end @@ -603,7 +608,7 @@ function conversation(a::T, userinput::Dict) where {T<:agent} :reward=> 0, :isterminal=> false, :evaluation=> nothing, - :feedback=> nothing, + :lesson=> nothing, :thoughtHistory=> OrderedDict{Symbol, Any}( # contain question, thought_1, action_1, observation_1, thought_2, ... # :recap=>, :question=> userinput[:text], diff --git a/src/llmfunction.jl b/src/llmfunction.jl index 68dd120..6956562 100644 --- a/src/llmfunction.jl +++ b/src/llmfunction.jl @@ -162,11 +162,29 @@ function virtualWineCustomerChatbox(a::T1, input::T2 :text=> prompt, ) ) - @show outgoingMsg - result = GeneralUtils.sendReceiveMqttMsg(outgoingMsg; timeout=120) - response = result[:response] - return (response[:text], response[:select], response[:reward], response[:isterminal]) + attempt = 0 + while attempt <= 5 + attempt += 1 + try + result = GeneralUtils.sendReceiveMqttMsg(outgoingMsg; timeout=120) + response = result[:response] + + return (response[:text], response[:select], response[:reward], response[:isterminal]) + catch e + io = IOBuffer() + showerror(io, e) + errorMsg = String(take!(io)) + st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace())) + println("") + @warn "Error occurred: $errorMsg\n$st" + println("") + end + + if attempt > 5 + error("virtualWineCustomerChatbox failed to get a response") + end + end end diff --git a/src/mcts.jl b/src/mcts.jl index 0c5aa24..4b72aad 100644 --- a/src/mcts.jl +++ b/src/mcts.jl @@ -137,17 +137,6 @@ function expand(a::T1, node::MCTSNode, decisionMaker::Function, nthSample = 0 while nthSample < n - try - - catch e - io = IOBuffer() - showerror(io, e) - errorMsg = String(take!(io)) - st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace())) - println("") - @warn "Error occurred: $errorMsg\n$st" - println("") - end thoughtDict = decisionMaker(a, node.state) @@ -160,8 +149,9 @@ function expand(a::T1, node::MCTSNode, decisionMaker::Function, if reward < 0 pprint(newstate[:thoughtHistory]) newstate[:evaluation] = stateevaluation - newstate[:feedback] = reflector(a, newstate) - print("done reflection") + newstate[:lesson] = reflector(a, newstate) + a.lesson[:lesson_1] = deepcopy(newstate) + print("---> reflector()") end if newNodeKey ∉ keys(node.children) diff --git a/src/type.jl b/src/type.jl index a86130f..3ecc0da 100644 --- a/src/type.jl +++ b/src/type.jl @@ -96,11 +96,12 @@ julia> agent = YiemAgent.bsommelier( """ chathistory::Vector{Dict{Symbol, Any}} = Vector{Dict{Symbol, Any}}() - maxHistoryMsg::Integer # 31th and earlier messages will get summarized + maxHistoryMsg::Integer # 21th and earlier messages will get summarized keywordinfo::Dict{Symbol, Any} = Dict{Symbol, Any}( :customerinfo => Dict{Symbol, Any}(), :storeinfo => Dict{Symbol, Any}(), - ) + ) + lesson::Dict{Symbol, Any} = Dict{Symbol, Any}() mctstree::Dict{Symbol, Any} = Dict{Symbol, Any}() # 1-historyPoint is in Dict{Symbol, Any} and compose of: