From b349c3a8b6c93fc38e7c43837d48309d55a81f36 Mon Sep 17 00:00:00 2001 From: narawat Date: Fri, 17 Jul 2026 07:01:55 +0700 Subject: [PATCH] update --- Project.toml | 2 +- src/interface.jl | 92 +++++++++++++++++++++++----------------------- src/llmfunction.jl | 17 +++++---- 3 files changed, 57 insertions(+), 54 deletions(-) diff --git a/Project.toml b/Project.toml index b8a7aa7..ea75dbc 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "YiemAgent" uuid = "e012c34b-7f78-48e0-971c-7abb83b6f0a2" -version = "0.6.5" +version = "0.7.0" authors = ["narawat lamaiin "] [deps] diff --git a/src/interface.jl b/src/interface.jl index 92ea76b..eacc7ec 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -75,7 +75,7 @@ OrderedDict{String, Any} with 4 entries: """ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10 ) where {T<:agent} - @info "YiemAgent decisionMaker() 1 " @__LINE__ + @info "YiemAgent decisionMaker() start " @__LINE__ # lessonDict = copy(JSON.parsefile("lesson.json")) # lesson = @@ -110,7 +110,7 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10 """ - @info "YiemAgent decisionMaker() 2 " @__LINE__ + # add context to text of the latest message (in the front). # use for loop because in openai format, each msg may contain both text and image. for d in a.chathistory[end]["content"] @@ -123,27 +123,27 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10 response = nothing # placeholder for show when error msg show up for attempt in 1:maxattempt - @info "YiemAgent decisionMaker() 3 " @__LINE__ + msg = Dict( "model" => "gemma-4-E4B-it-UD-Q4_K_XL", "messages" => a.chathistory, "temperature" => 0.7 ) - @info "YiemAgent decisionMaker() 4 " @__LINE__ + response = a.context.text2textInstructLLM(a.id, msg) - @info "YiemAgent decisionMaker() 5 " @__LINE__ + response = GeneralUtils.clean_json_response(response) response = GeneralUtils.remove_french_accents(response) think, response = GeneralUtils.extractthink(response) response = String(split(response, ", observation")[1]) # in case LLM generate observation key which it isn't supposed to response = strip(response) - @info "YiemAgent decisionMaker() 6 " @__LINE__ + # dollar sign in Julia means string interpolation while occursin('$', response) response = replace(response, '$' => "USD") end - @info "YiemAgent decisionMaker() 7 " @__LINE__ + responsedict = nothing if occursin(requiredKeys[2], response) try @@ -157,22 +157,22 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10 println("\nERROR YiemAgent decisionMaker() $errornote --(not qualify response)-> $responsedict ", @__FILE__, ":", @__LINE__, " $(Dates.now())\n") continue end - @info "YiemAgent decisionMaker() 8 " @__LINE__ + # check whether all answer's key points are in responsedict println("\n---") println(responsedict) println("---\n") ispass, errormsg = GeneralUtils.checkAgentResponse_JSON(responsedict, requiredKeys) - @info "YiemAgent decisionMaker() 9 " @__LINE__ + if !ispass errornote = errormsg println("\nERROR YiemAgent decisionMaker() $errornote --(not qualify response)-> $responsedict ", @__FILE__, ":", @__LINE__, " $(Dates.now())\n") continue end - @info "YiemAgent decisionMaker() 10 " @__LINE__ + if responsedict["action_input"] == "CHAT_BOX" && occursin("similar", responsedict["action_input"]) - @info "illegal CHAT_BOX search term" @__LINE__ + continue end @@ -184,7 +184,7 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10 # println("\nYiem decisionMaker() ", @__FILE__, ":", @__LINE__, " $(Dates.now())") # pprintln(responsedict) - @info "YiemAgent decisionMaker() 11 " @__LINE__ + @info "YiemAgent decisionMaker() end " @__LINE__ return responsedict end error("DecisionMaker failed to generate a thought ", response) @@ -359,7 +359,7 @@ message => Dict( function conversation(a::sommelier; userinput::Union{Dict{String, Any}, JSON.Object{String, Any}}, maximumMsg=50, max_think_loop::Integer=3) - @info "YiemAgent conversation() 0 " @__LINE__ + @info "YiemAgent conversation() start " @__LINE__ userinput = GeneralUtils.dictify(userinput; keytype=String, sort_order=["text"]) # find text in usermsg @@ -375,7 +375,7 @@ function conversation(a::sommelier; userinput::Union{Dict{String, Any}, JSON.Obj clearhistory(a) return "Okay. What shall we talk about?" else - @info "YiemAgent conversation() 1 " @__LINE__ + # add usermsg to a.chathistory but how do I handle images? addNewMessage(a, "user", userinput; maximumMsg=maximumMsg) @@ -384,9 +384,9 @@ function conversation(a::sommelier; userinput::Union{Dict{String, Any}, JSON.Obj while true loopcount += 1 if loopcount > max_think_loop - @info "YiemAgent conversation() 1-1 think count $loopcount " @__LINE__ + thoughtdict, result_raw = generatechat!(a) - @info "YiemAgent conversation() 1-2 think count $loopcount " @__LINE__ + assistant_response = Dict{String, Any}( "role" => "assistant", @@ -414,15 +414,15 @@ function conversation(a::sommelier; userinput::Union{Dict{String, Any}, JSON.Obj ), ] ) - @info "YiemAgent conversation() 1-3 think count $loopcount " @__LINE__ + return response_to_frontend end - @info "YiemAgent conversation() 2-3 think count $loopcount " @__LINE__ + thoughtdict, result_raw = think(a) - @info "YiemAgent conversation() 2-4 think count $loopcount " @__LINE__ + if thoughtdict["action_name"] ∈ ["CHAT_BOX"] - @info "YiemAgent conversation() 2-5 think count $loopcount " @__LINE__ + assistant_response = Dict{String, Any}( "role" => "assistant", @@ -477,28 +477,28 @@ function conversation(a::sommelier; userinput::Union{Dict{String, Any}, JSON.Obj ) """ - @info "YiemAgent conversation() 2-6 think count $loopcount " @__LINE__ + return response_to_frontend else # still in action - @info "YiemAgent conversation() 2-7 think count $loopcount " @__LINE__ + action_name = thoughtdict["action_name"] action_input = thoughtdict["action_input"] - @info "YiemAgent conversation() 2-8 think count $loopcount " @__LINE__ + action_call = Dict{String, Any}( "role" => "action_call", "content" => [Dict("type" => "text", "text" => "{action_name: $action_name, action_input: $action_input}"),] ) - @info "YiemAgent conversation() 2-9 think count $loopcount " @__LINE__ + addNewMessage(a, "action_call", action_call; maximumMsg=maximumMsg) - @info "YiemAgent conversation() 2-10 think count $loopcount " @__LINE__ + action_result = thoughtdict["action_result"] actionresult = Dict{String, Any}( "role" => "action_result", "content" => [Dict("type" => "text", "text" => "$action_result"),] ) - @info "YiemAgent conversation() 2-11 think count $loopcount " @__LINE__ + addNewMessage(a, "actionresult", actionresult; maximumMsg=maximumMsg) - @info "YiemAgent conversation() 2-12 think count $loopcount " @__LINE__ + @info "YiemAgent conversation() end think count $loopcount " @__LINE__ end end end @@ -518,26 +518,27 @@ julia> """ function think(a::T)::NamedTuple{(:thoughtdict, :result_raw), Tuple{OrderedDict, Any}} where {T<:agent} # a.memory[:recap] = generateSituationReport(a, a.context["text"2textInstructLLM]; skiprecent=0) - @info "YiemAgent think() 1-1 " @__LINE__ + @info "YiemAgent think() start " @__LINE__ thoughtdict = decisionMaker(a) - @info "YiemAgent think() 1-2 " @__LINE__ - # pprintln(thoughtdict) + @info "YiemAgent think() 1 " @__LINE__ + @show thoughtdict + println("---\n") result_raw = nothing if thoughtdict["action_name"] ∈ ["CHAT_BOX"] - @info "YiemAgent think() 2-1 " @__LINE__ + thoughtdict, result_raw = generatechat!(a) - @info "YiemAgent think() 2-2 " @__LINE__ + elseif thoughtdict["action_name"] == "END_CONVER_GUIDELINE" - @info "YiemAgent think() 3 " @__LINE__ + thoughtdict, result_raw = end_conversation_guideline!(a, thoughtdict) elseif thoughtdict["action_name"] ∈ ["WINE_PRESENTATION_GUIDELINE"] - @info "YiemAgent think() 4 " @__LINE__ + thoughtdict, result_raw = wine_presentation_guideline!(a, thoughtdict) elseif thoughtdict["action_name"] == "SEARCH_WINE_DATABASE" - @info "YiemAgent think() 5 " @__LINE__ + thoughtdict, result_raw = search_wine_database!(a, thoughtdict; useSQLLLM=false) if result_raw !== nothing && result_raw isa Vector if haskey(a.memory["shortmem"], "items_info") @@ -548,12 +549,13 @@ function think(a::T)::NamedTuple{(:thoughtdict, :result_raw), Tuple{OrderedDict, end else - @info "YiemAgent think() 6 " @__LINE__ + error("condition is not defined ", @__FILE__, ":", @__LINE__, " $(Dates.now())") end - println("\n") + + @info "YiemAgent think() end " @__LINE__ @show thoughtdict - @info "YiemAgent think() 7 " @__LINE__ + println("---\n") return (thoughtdict=thoughtdict, result_raw=result_raw) end @@ -630,7 +632,7 @@ end #PENDING function generatechat!(a::T; maxattempt::Integer=10 )::NamedTuple{(:thoughtdict, :result_raw), Tuple{OrderedDict, Any}} where {T<:agent} - + @info "YiemAgent generatechat!() start " @__LINE__ # lessonDict = copy(JSON.parsefile("lesson.json")) # lesson = @@ -713,7 +715,7 @@ function generatechat!(a::T; maxattempt::Integer=10 "action_name": "...", "action_input": "..." """ - @info "YiemAgent generatechat!() 1 " @__LINE__ + system_msg = Dict( "role" => "system", "content" => [ @@ -728,7 +730,7 @@ function generatechat!(a::T; maxattempt::Integer=10 errornote = "N/A" response = nothing # placeholder for show when error msg show up - @info "YiemAgent generatechat!() 2 " @__LINE__ + for attempt in 1:maxattempt if attempt > 1 println("\nYiemAgent generatechat() attempt $attempt/$maxattempt ", @__FILE__, ":", @__LINE__, " $(Dates.now())") @@ -746,7 +748,7 @@ function generatechat!(a::T; maxattempt::Integer=10 think, response = GeneralUtils.extractthink(response) response = strip(response) - @info "YiemAgent generatechat!() 3 " @__LINE__ + responsedict = nothing if occursin(requiredKeys[2], response) try @@ -761,7 +763,7 @@ function generatechat!(a::T; maxattempt::Integer=10 continue end - @info "YiemAgent generatechat!() 4 " @__LINE__ + # check whether all answer's key points are in responsedict ispass, errormsg = GeneralUtils.checkAgentResponse_JSON(responsedict, requiredKeys) if !ispass @@ -769,7 +771,7 @@ function generatechat!(a::T; maxattempt::Integer=10 println("\nERROR YiemAgent generatechat() $errornote --(not qualify response)> $responsedict ", @__FILE__, ":", @__LINE__, " $(Dates.now())\n") continue end - @info "YiemAgent generatechat!() 5 " @__LINE__ + # if responsedict["action_name"] ∉ ["CHAT_BOX", "SEARCH_WINE_DATABASE", "PRESENT_WINE_GUIDELINE", "END_CONVER_GUIDELINE"] # errornote = "Your previous attempt didn't use the given functions" # println("\nERROR YiemAgent decisionMaker() $errornote --(not qualify response)--> $(responsedict["action_name"])", @__FILE__, ":", @__LINE__, " $(Dates.now())") @@ -779,7 +781,7 @@ function generatechat!(a::T; maxattempt::Integer=10 # println("\nYiem decisionMaker() ", @__FILE__, ":", @__LINE__, " $(Dates.now())") # pprintln(responsedict) responsedict["action_result"] = "Action result is the next user dialogue." - @info "YiemAgent generatechat!() 6 " @__LINE__ + @info "YiemAgent generatechat!() end " @__LINE__ return (thoughtdict=responsedict, result_raw=responsedict["action_input"]) end error("YiemAgent generatechat() failed to generate a thought ", response) diff --git a/src/llmfunction.jl b/src/llmfunction.jl index 21b566b..b47d29f 100644 --- a/src/llmfunction.jl +++ b/src/llmfunction.jl @@ -810,7 +810,7 @@ function extractWineAttributes_1(a::T1, input::T2; maxattempt=10 responsedict[k] = _v end - println("\n--- extractWineAttributes_1-1()") + @info "YiemAgent extractWineAttributes_1() " @__LINE__ @show responsedict @info "---\n" @__LINE__ @@ -832,9 +832,11 @@ function extractWineAttributes_1(a::T1, input::T2; maxattempt=10 end result = result[1:end-2] # remove the ending ", " - println("\n--- extractWineAttributes_1-2()") + + @info "YiemAgent extractWineAttributes_1() " @__LINE__ @show result @info "---\n" @__LINE__ + return result end error("extractWineAttributes_1() failed to get a response") @@ -987,9 +989,6 @@ function extractWineAttributes_2(a::T1, input::T2)::String where {T1<:agent, T2< for attempt in 1:10 response = a.context.text2textInstructLLM(a.id, msg) response = GeneralUtils.clean_json_response(response) - println("\n--- extractWineAttributes_2-1()") - println(response) - println("--- \n") response = GeneralUtils.remove_french_accents(response) think, response = GeneralUtils.extractthink(response) @@ -1027,9 +1026,11 @@ function extractWineAttributes_2(a::T1, input::T2)::String where {T1<:agent, T2< end end result = result[1:end-2] # remove the ending ", " - println("\n--- extractWineAttributes_2-2()") - println(result) - println("--- \n") + + @info "YiemAgent extractWineAttributes_2() " @__LINE__ + @show result + @info "---\n" @__LINE__ + return result end error("extractWineAttributes_2() failed to get a response")