diff --git a/Manifest.toml b/Manifest.toml index e3545fd..87212f2 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.12.6" manifest_format = "2.0" -project_hash = "95dc0193a18325ca5b1e37deab8108d1b35915db" +project_hash = "a2c996ffe370e277cbff80af974d2701698f1b6c" [[deps.Accessors]] deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"] @@ -760,11 +760,11 @@ version = "0.7.0" [[deps.SQLLLM]] deps = ["CSV", "DataFrames", "DataStructures", "Dates", "FileIO", "GeneralUtils", "HTTP", "JSON", "LLMMCTS", "LibPQ", "PrettyPrinting", "Random", "Revise", "StatsBase", "Tables", "URIs", "UUIDs"] -git-tree-sha1 = "8f264038c55c5bea069cccbdc057c56e27899c42" +git-tree-sha1 = "2807a768907f59308d8d71ece599037b0a66b0a5" repo-rev = "main" repo-url = "https://git.yiem.cc/ton/SQLLLM" uuid = "2ebc79c7-cc10-4a3a-9665-d2e1d61e63d3" -version = "0.2.6" +version = "0.2.7" [[deps.SQLStrings]] git-tree-sha1 = "55de0530689832b1d3d43491ee6b67bd54d3323c" @@ -986,7 +986,7 @@ version = "1.6.1" deps = ["CSV", "DataFrames", "DataStructures", "Dates", "GeneralUtils", "HTTP", "JSON", "LLMMCTS", "LibPQ", "NATS", "PrettyPrinting", "Random", "Revise", "Serialization", "URIs", "UUIDs"] path = "." uuid = "e012c34b-7f78-48e0-971c-7abb83b6f0a2" -version = "0.4.1" +version = "0.4.2" [[deps.Zlib_jll]] deps = ["Libdl"] diff --git a/Project.toml b/Project.toml index 396faff..8a2cf4d 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "YiemAgent" uuid = "e012c34b-7f78-48e0-971c-7abb83b6f0a2" -version = "0.4.2" +version = "0.4.3" authors = ["narawat lamaiin "] [deps] @@ -30,4 +30,4 @@ HTTP = "2.4.0" JSON = "1.6.1" LLMMCTS = "0.1.5" NATS = "0.1.0" -SQLLLM = "0.2.6" +SQLLLM = "0.2.7" diff --git a/src/interface.jl b/src/interface.jl index 24f35d7..aba050f 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -358,7 +358,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() 1" @__LINE__ + @info "YiemAgent conversation() 1 " @__LINE__ userinput = GeneralUtils.dictify(userinput; keytype=String, sort_order=["text"]) # find text in usermsg @@ -374,7 +374,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() 2" @__LINE__ + @info "YiemAgent conversation() 2 " @__LINE__ # add usermsg to a.chathistory but how do I handle images? addNewMessage(a, "user", userinput; maximumMsg=maximumMsg) @@ -382,10 +382,17 @@ function conversation(a::sommelier; userinput::Union{Dict{String, Any}, JSON.Obj loopcount = 0 while true loopcount += 1 - @info "YiemAgent conversation() 2-0 count $loopcount" @__LINE__ + if loopcount > max_think_loop + @info "YiemAgent conversation() 2-1 think count $loopcount " @__LINE__ + r = generatechat(a) + @info "YiemAgent conversation() 2-2 think count $loopcount " @__LINE__ + return r + end + + @info "YiemAgent conversation() 2-3 think count $loopcount " @__LINE__ thoughtdict, _ = think(a) if thoughtdict["action_name"] ∈ ["CHAT_BOX"] - @info "YiemAgent conversation() 2-1" @__LINE__ + @info "YiemAgent conversation() 2-4 think count $loopcount " @__LINE__ assistant_response = Dict{String, Any}( "role" => "assistant", "content" => [Dict("type" => "text", "text" => thoughtdict["action_input"]),] @@ -393,13 +400,6 @@ function conversation(a::sommelier; userinput::Union{Dict{String, Any}, JSON.Obj addNewMessage(a, "assistant", assistant_response; maximumMsg=maximumMsg) return thoughtdict["action_input"] end - - if loopcount > max_think_loop - @info "YiemAgent conversation() 2-2" @__LINE__ - r = generatechat(a) - @info "YiemAgent conversation() 2-3" @__LINE__ - return r - end end end end @@ -419,29 +419,29 @@ 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) thoughtdict = decisionMaker(a) - @info "YiemAgent think() 1" @__LINE__ + @info "YiemAgent think() 1 " @__LINE__ # pprintln(thoughtdict) result_raw = nothing if thoughtdict["action_name"] ∈ ["CHAT_BOX"] - @info "YiemAgent think() 2" @__LINE__ + @info "YiemAgent think() 2 " @__LINE__ thoughtdict, result_raw = chatbox!(a, thoughtdict) elseif thoughtdict["action_name"] == "END_CONVER_GUIDELINE" - @info "YiemAgent think() 3" @__LINE__ + @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__ + @info "YiemAgent think() 4 " @__LINE__ thoughtdict, result_raw = wine_presentation_guideline!(a, thoughtdict) elseif thoughtdict["action_name"] == "CHECK_WINE" - @info "YiemAgent think() 5" @__LINE__ + @info "YiemAgent think() 5 " @__LINE__ thoughtdict, result_raw = checkwine!(a, thoughtdict) else - @info "YiemAgent think() 6" @__LINE__ + @info "YiemAgent think() 6 " @__LINE__ error("condition is not defined ", @__FILE__, ":", @__LINE__, " $(Dates.now())") end @@ -454,7 +454,7 @@ function think(a::T)::NamedTuple{(:thoughtdict, :result_raw), Tuple{OrderedDict, end a.memory["shortmem"]["$(max_ind + 1)"] = thoughtdict - @info "YiemAgent think() 7" @__LINE__ + @info "YiemAgent think() 7 " @__LINE__ pprintln(thoughtdict) return (thoughtdict=thoughtdict, result_raw=result_raw) end diff --git a/src/type.jl b/src/type.jl index a11af7d..afab392 100644 --- a/src/type.jl +++ b/src/type.jl @@ -267,24 +267,24 @@ function sommelier( - Answering questions or offering additional services beyond those related to your store's wine recommendations such as discounts, quantity, rewards programs, promotions, delivery options, shipping, boxes, gift wrapping, packaging, personalized messages or something similar. These are the job of our sales team at the store. # you should then respond to the user with interleaving plan, action_name, action_input - 1) **plan**, Based on the current situation, state a complete action plan to complete the task and rationale. Be specific. - 2) **action_name**, (Typically corresponds to the execution of the first step in your plan) Can be one of the available_actions name - 3) **action_input**, The input to the action you are about to perform according to your plan. + 1) "plan", Based on the current situation, state a complete action plan to complete the task and rationale. Be specific. + 2) "action_name", (Typically corresponds to the execution of the first step in your plan) Can be one of the available_actions name + 3) "action_input", The input to the action you are about to perform according to your plan. After the action is executed you gets "action_result". It is the output from the action you selected. - # you should only respond in JSON format as described below + # you should only respond in JSON format as described below (not Markdown format) "plan": "...", "action_name": "...", "action_input": "..." # available actions - **CHAT_BOX**, which you can use to talk with the user. The input is dialogue you want to chat with the user according to your plan. - **CHECK_WINE**, allows you to check information about wines you want in your inventory's database. The input is text that specify supported search criteria includeing: retailer_name, wine price, winery, name, vintage, region, country, type, grape varietal, tasting notes, occasion, food pairing, intensity, tannin, sweetness, and acidity. + "CHAT_BOX", which you can use to talk with the user. The input is dialogue you want to chat with the user according to your plan. + "CHECK_WINE", allows you to check information about wines you want in your inventory's database. The input is text that specify supported search criteria includeing: retailer_name, wine price, winery, name, vintage, region, country, type, grape varietal, tasting notes, occasion, food pairing, intensity, tannin, sweetness, and acidity. Example query 1: "Dry, full-bodied red wine from 1) region: Burgundy, country: France or 2) region: Tuscany, country: Italy. Grape varietal: Merlot or Syrah. price 100 to 1000 USD." Example query 2: "Red or white wine, medium tannin, price under 700 USD" Example query 3: "white wine, region: Tuscany or Bordeaux, country: Italy or France - **WINE_PRESENTATION_GUIDELINE**, which you can use to check the store guidelines about how to present wines you have found to the user. The input is "nothing" keyword. The output is the guidelines that you can follow. - **END_CONVER_GUIDELINE**, which you can use to check the store guidelines about how to end the conversation with the user. The input is "nothing" keyword. The output is the guidelines that you can follow. + "WINE_PRESENTATION_GUIDELINE", which you can use to check the store guidelines about how to present wines you have found to the user. The input is "nothing" keyword. The output is the guidelines that you can follow. + "END_CONVER_GUIDELINE", which you can use to check the store guidelines about how to end the conversation with the user. The input is "nothing" keyword. The output is the guidelines that you can follow. """