This commit is contained in:
narawat lamaiin
2024-08-22 08:46:08 +07:00
parent 50af07c1f0
commit 9e13990007
3 changed files with 199 additions and 355 deletions

View File

@@ -26,9 +26,9 @@ uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35"
version = "0.1.9"
[[deps.CEnum]]
git-tree-sha1 = "eb4cb44a499229b3b8426dcfb5dd85333951ff90"
git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc"
uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82"
version = "0.4.2"
version = "0.5.0"
[[deps.CSV]]
deps = ["CodecZlib", "Dates", "FilePathsBase", "InlineStrings", "Mmap", "Parsers", "PooledArrays", "PrecompileTools", "SentinelArrays", "Tables", "Unicode", "WeakRefStrings", "WorkerUtilities"]
@@ -36,29 +36,23 @@ git-tree-sha1 = "6c834533dc1fabd820c1db03c839bf97e45a3fab"
uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
version = "0.10.14"
[[deps.Calculus]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad"
uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9"
version = "0.5.1"
[[deps.CodeTracking]]
deps = ["InteractiveUtils", "UUIDs"]
git-tree-sha1 = "c0216e792f518b39b22212127d4a84dc31e4e386"
git-tree-sha1 = "7eee164f122511d3e4e1ebadb7956939ea7e1c77"
uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
version = "1.3.5"
version = "1.3.6"
[[deps.CodecZlib]]
deps = ["TranscodingStreams", "Zlib_jll"]
git-tree-sha1 = "b8fe8546d52ca154ac556809e10c75e6e7430ac8"
git-tree-sha1 = "bce6804e5e6044c6daab27bb533d1295e4a2e759"
uuid = "944b1d66-785c-5afd-91f1-9de20f533193"
version = "0.7.5"
version = "0.7.6"
[[deps.Compat]]
deps = ["TOML", "UUIDs"]
git-tree-sha1 = "b1c55339b7c6c350ee89f2c1604299660525b248"
git-tree-sha1 = "8ae8d32e09f0dcf42a36b90d4e17f5dd2e4c4215"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "4.15.0"
version = "4.16.0"
weakdeps = ["Dates", "LinearAlgebra"]
[deps.Compat.extensions]
@@ -77,9 +71,9 @@ version = "2.4.2"
[[deps.CondaPkg]]
deps = ["JSON3", "Markdown", "MicroMamba", "Pidfile", "Pkg", "Preferences", "TOML"]
git-tree-sha1 = "e81c4263c7ef4eca4d645ef612814d72e9255b41"
git-tree-sha1 = "8f7faef2ca039ee068cd971a80ccd710d23fb2eb"
uuid = "992eb4ea-22a4-4c89-a5bb-47a3300528ab"
version = "0.2.22"
version = "0.2.23"
[[deps.Crayons]]
git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15"
@@ -124,15 +118,17 @@ version = "0.4.1"
[[deps.DispatchDoctor]]
deps = ["MacroTools", "Preferences"]
git-tree-sha1 = "32d236e685d028f5bc808aae0634b58aac5128f0"
git-tree-sha1 = "c2acd1de2c4c357928f9fb6b60b402d914621378"
uuid = "8d63f2c5-f18a-4cf2-ba9d-b3f60fc568c8"
version = "0.4.10"
version = "0.4.14"
[deps.DispatchDoctor.extensions]
DispatchDoctorChainRulesCoreExt = "ChainRulesCore"
DispatchDoctorEnzymeCoreExt = "EnzymeCore"
[deps.DispatchDoctor.weakdeps]
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869"
[[deps.Distributed]]
deps = ["Random", "Serialization", "Sockets"]
@@ -140,9 +136,9 @@ uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"
[[deps.Distributions]]
deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"]
git-tree-sha1 = "9c405847cc7ecda2dc921ccf18b47ca150d7317e"
git-tree-sha1 = "0e0a1264b0942f1f3abb2b30891f2a590cc652ac"
uuid = "31c24e10-a181-5473-b8eb-7969acd0382f"
version = "0.25.109"
version = "0.25.110"
[deps.Distributions.extensions]
DistributionsChainRulesCoreExt = "ChainRulesCore"
@@ -165,12 +161,6 @@ deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"]
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
version = "1.6.0"
[[deps.DualNumbers]]
deps = ["Calculus", "NaNMath", "SpecialFunctions"]
git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566"
uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74"
version = "0.6.8"
[[deps.ExceptionUnwrapping]]
deps = ["Test"]
git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a"
@@ -199,9 +189,9 @@ uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"
[[deps.FillArrays]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "0653c0a2396a6da5bc4766c43041ef5fd3efbe57"
git-tree-sha1 = "fd0002c0b5362d7eb952450ad5eb742443340d6e"
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
version = "1.11.0"
version = "1.12.0"
weakdeps = ["PDMats", "SparseArrays", "Statistics"]
[deps.FillArrays.extensions]
@@ -232,10 +222,16 @@ uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
version = "1.10.8"
[[deps.HypergeometricFunctions]]
deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"]
git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685"
deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"]
git-tree-sha1 = "7c4195be1649ae622304031ed46a2f4df989f1eb"
uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a"
version = "0.3.23"
version = "0.3.24"
[[deps.ICU_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "20b6765a3016e1fca0c9c93c80d50061b94218b7"
uuid = "a51ab1cf-af8e-5615-a023-bc2c838bba6b"
version = "69.1.0+0"
[[deps.Infinity]]
deps = ["Dates", "Random", "Requires"]
@@ -306,9 +302,9 @@ version = "1.14.0"
[[deps.JuliaInterpreter]]
deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"]
git-tree-sha1 = "a6adc2dcfe4187c40dc7c2c9d2128e326360e90a"
git-tree-sha1 = "7ae67d8567853d367e3463719356b8989e236069"
uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a"
version = "0.9.32"
version = "0.9.34"
[[deps.Kerberos_krb5_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
@@ -357,15 +353,15 @@ version = "1.6.4+0"
[[deps.LibPQ]]
deps = ["CEnum", "DBInterface", "Dates", "Decimals", "DocStringExtensions", "FileWatching", "Infinity", "Intervals", "IterTools", "LayerDicts", "LibPQ_jll", "Libdl", "Memento", "OffsetArrays", "SQLStrings", "Tables", "TimeZones", "UTCDateTimes"]
git-tree-sha1 = "74feb1a63ebbcdcf1730016d2a4dfad0a655404f"
git-tree-sha1 = "3d227cd13cbf1e9a54d7748dab33e078da6f9168"
uuid = "194296ae-ab2e-5f79-8cd4-7183a0a5a0d1"
version = "1.17.1"
version = "1.18.0"
[[deps.LibPQ_jll]]
deps = ["Artifacts", "JLLWrappers", "Kerberos_krb5_jll", "Libdl", "OpenSSL_jll", "Pkg"]
git-tree-sha1 = "a299629703a93d8efcefccfc16b18ad9a073d131"
deps = ["Artifacts", "ICU_jll", "JLLWrappers", "Kerberos_krb5_jll", "Libdl", "OpenSSL_jll", "Zstd_jll"]
git-tree-sha1 = "09163f837936c8cc44f4691cb41d805eb1769642"
uuid = "08be9ffa-1c94-5ee5-a977-46a84ec9b350"
version = "14.3.0+1"
version = "16.0.0+0"
[[deps.LibSSH2_jll]]
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
@@ -406,9 +402,9 @@ version = "1.0.3"
[[deps.LoweredCodeUtils]]
deps = ["JuliaInterpreter"]
git-tree-sha1 = "eeaedcf337f33c039f9f3a209a8db992deefd7e9"
git-tree-sha1 = "1ce1834f9644a8f7c011eb0592b7fd6c42c90653"
uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b"
version = "2.4.8"
version = "3.0.1"
[[deps.MQTTClient]]
deps = ["Distributed", "Random", "Sockets"]
@@ -464,20 +460,14 @@ uuid = "a63ad114-7e13-5084-954f-fe012c677804"
[[deps.Mocking]]
deps = ["Compat", "ExprTools"]
git-tree-sha1 = "bf17d9cb4f0d2882351dfad030598f64286e5936"
git-tree-sha1 = "2c140d60d7cb82badf06d8783800d0bcd1a7daa2"
uuid = "78c3b35d-d492-501b-9361-3d52fe80e533"
version = "0.7.8"
version = "0.8.1"
[[deps.MozillaCACerts_jll]]
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"
version = "2023.1.10"
[[deps.NaNMath]]
deps = ["OpenLibm_jll"]
git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4"
uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
version = "1.0.2"
[[deps.NetworkOptions]]
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
version = "1.2.0"
@@ -511,9 +501,9 @@ version = "1.4.3"
[[deps.OpenSSL_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"]
git-tree-sha1 = "a12e56c72edee3ce6b96667745e6cbbe5498f200"
git-tree-sha1 = "a028ee3cb5641cccc4c24e90c36b0a4f7707bdf5"
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
version = "1.1.23+0"
version = "3.0.14+0"
[[deps.OpenSpecFun_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
@@ -589,15 +579,15 @@ version = "1.2.0"
[[deps.PythonCall]]
deps = ["CondaPkg", "Dates", "Libdl", "MacroTools", "Markdown", "Pkg", "REPL", "Requires", "Serialization", "Tables", "UnsafePointers"]
git-tree-sha1 = "8de9e6cbabc9bcad4f325bd9f2f1e83361e5037d"
git-tree-sha1 = "84084218c7377beb15a317868d4541a8c3c4ac99"
uuid = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d"
version = "0.9.20"
version = "0.9.22"
[[deps.QuadGK]]
deps = ["DataStructures", "LinearAlgebra"]
git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e"
git-tree-sha1 = "e237232771fdafbae3db5c31275303e056afaa9f"
uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
version = "2.9.4"
version = "2.10.1"
[[deps.REPL]]
deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"]
@@ -625,10 +615,10 @@ uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.3.0"
[[deps.Revise]]
deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "Requires", "UUIDs", "Unicode"]
git-tree-sha1 = "85ddd93ea15dcd8493400600e09104a9e94bb18d"
deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "REPL", "Requires", "UUIDs", "Unicode"]
git-tree-sha1 = "7b7850bb94f75762d567834d7e9802fc22d62f9c"
uuid = "295af30f-e4ad-537b-8983-00126c2a3abe"
version = "3.5.15"
version = "3.5.18"
[[deps.Rmath]]
deps = ["Random", "Rmath_jll"]
@@ -638,9 +628,9 @@ version = "0.7.1"
[[deps.Rmath_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"]
git-tree-sha1 = "d483cd324ce5cf5d61b77930f0bbd6cb61927d21"
git-tree-sha1 = "e60724fd3beea548353984dc61c943ecddb0e29a"
uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f"
version = "0.4.2+0"
version = "0.4.3+0"
[[deps.SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
@@ -773,10 +763,10 @@ uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
version = "1.0.1"
[[deps.Tables]]
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"]
git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d"
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"]
git-tree-sha1 = "598cd7c1f68d1e205689b1c2fe65a9f85846f297"
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
version = "1.11.1"
version = "1.12.0"
[[deps.Tar]]
deps = ["ArgTools", "SHA"]
@@ -789,22 +779,18 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
[[deps.TimeZones]]
deps = ["Dates", "Downloads", "InlineStrings", "Mocking", "Printf", "Scratch", "TZJData", "Unicode", "p7zip_jll"]
git-tree-sha1 = "a6ae8d7a27940c33624f8c7bde5528de21ba730d"
git-tree-sha1 = "b92aebdd3555f3a7e3267cf17702033c2814ef48"
uuid = "f269a46b-ccf7-5d73-abea-4c690281aa53"
version = "1.17.0"
version = "1.18.0"
weakdeps = ["RecipesBase"]
[deps.TimeZones.extensions]
TimeZonesRecipesBaseExt = "RecipesBase"
[[deps.TranscodingStreams]]
git-tree-sha1 = "60df3f8126263c0d6b357b9a1017bb94f53e3582"
git-tree-sha1 = "e84b3a11b9bece70d14cce63406bbc79ed3464d2"
uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
version = "0.11.0"
weakdeps = ["Random", "Test"]
[deps.TranscodingStreams.extensions]
TestExt = ["Test", "Random"]
version = "0.11.2"
[[deps.URIs]]
git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b"
@@ -845,6 +831,12 @@ deps = ["Libdl"]
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"
version = "1.2.13+1"
[[deps.Zstd_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"]
git-tree-sha1 = "e678132f07ddb5bfa46857f0d7620fb9be675d3b"
uuid = "3161d3a3-bdf6-5164-811a-617609db77b4"
version = "1.5.6+0"
[[deps.libblastrampoline_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "8e850b90-86db-534c-a0d3-1478176c7d93"

View File

@@ -149,7 +149,7 @@ function sommelier(
:activeplan => Dict{Symbol, Any}(), # current using plan
:currenttrajectory=> Dict{Symbol, Any}(), # store question, thought, action, observation, ...
)
),
mctsWorkDict::Dict{Symbol, Any} = Dict{Symbol, Any}()
)

View File

@@ -341,21 +341,21 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol, Any} where {T<:age
response = a.text2textInstructLLM(prompt)
responsedict = GeneralUtils.textToDict(response,
["Understanding", "Reasoning", "Plan", "Action_name", "Action_input", "Mentioning_wine"],
rightmarker=":", symbolkey=true)
rightmarker=":", symbolkey=true, lowercasekey=true)
if responsedict[:Action_name] ["CHATBOX", "PRESENTBOX", "CHECKINVENTORY", "ENDCONVERSATION"]
if responsedict[:action_name] ["CHATBOX", "PRESENTBOX", "CHECKINVENTORY", "ENDCONVERSATION"]
errornote = "You must use the given functions"
error("You must use the given functions ", @__FILE__, " ", @__LINE__)
end
for i [:Understanding, :Plan, :Action_name]
for i [:understanding, :plan, :action_name]
if length(responsedict[i]) == 0
error("$i is empty ", @__FILE__, " ", @__LINE__)
end
end
# check if there are more than 1 key per categories
for i [:Understanding, :Plan, :Action_name, :Action_input, :Mentioning_wine]
for i [:understanding, :plan, :action_name, :action_input, :mentioning_wine]
matchkeys = GeneralUtils.findMatchingDictKey(responsedict, i)
if length(matchkeys) > 1
error("DecisionMaker has more than one key per categories")
@@ -368,13 +368,13 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol, Any} where {T<:age
# check if LLM recommend wine before checking inventory
isMemEmpty = isempty(a.memory[:shortmem])
if occursin("Yes", responsedict[:Mentioning_wine]) && isMemEmpty &&
responsedict[:Action_name] != "CHECKINVENTORY"
if occursin("Yes", responsedict[:mentioning_wine]) && isMemEmpty &&
responsedict[:action_name] != "CHECKINVENTORY"
errornote = "Note: You can't recommend wines yet. You must check your inventory before recommending wine to the user."
error( "You can't recommend wines yet. You must check your inventory before recommending wines")
elseif responsedict[:Action_name] == "PRESENTBOX" && isMemEmpty &&
responsedict[:Action_name] != "CHECKINVENTORY"
elseif responsedict[:action_name] == "PRESENTBOX" && isMemEmpty &&
responsedict[:action_name] != "CHECKINVENTORY"
errornote = "Note: You can't recommend wines yet. You must check your inventory before recommending wine to the user."
error( "You can't recommend wines yet. You must check your inventory before recommending wines")
@@ -382,7 +382,7 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol, Any} where {T<:age
errornote = ""
end
delete!(responsedict, :Mentioning_wine)
delete!(responsedict, :mentioning_wine)
return responsedict
catch e
@@ -903,23 +903,6 @@ function conversation(a::T, userinput::Dict) where {T<:agent}
# thought will be added to chat model via context
chatresponse = generatechat(a.memory, a.chathistory, a.text2textInstructLLM)
# some time LLM said to user that it (checking inventory) but it is not.
# if chatresponse want to check inventory but think() didn't checkinventory then do it
llmCheckInv = occursin("(check", chatresponse) || occursin("*check", chatresponse) ||
occursin("inventory)", chatresponse) || occursin("inventory*", chatresponse)
if llmCheckInv && actionname != "checkinventory"
error("force check inventory should not be called")
actionname, result = forceInventoryCheck(a)
push!(a.memory[:shortmem], Dict(Symbol(actionname)=> result))
# generate chatresponse again because we have force inventory check
chatresponse = generatechat(a.memory, a.chathistory, a.text2textInstructLLM)
else
# since chatresponse does not halucinate i.e. no (check inventory), it does not need
# to regenerate again and con be use directly
end
addNewMessage(a, "assistant", chatresponse)
push!(a.memory[:events],
@@ -955,21 +938,10 @@ function think(a::T)::NamedTuple{(:actionname, :result), Tuple{String, String}}
a.memory[:recap] = generateSituationReport(a, a.text2textInstructLLM; skiprecent=5)
a.memory[:QandA] = generatequestion(a, a.text2textInstructLLM; recent=5)
dummy = situationtrack(a, a.text2textInstructLLM)
# after the user selected their wine. No question should be asked
# a.memory[:QandA] =
# if occursin("None", a.memory[:sitrep][:wine_selected])
# generatequestion(a, a.text2textInstructLLM)
# else
# generatequestion(a, a.text2textInstructLLM) #[PENDING] to be removed. this is just for explor
# "None"
# end
thoughtDict = decisionMaker(a; recent=5)
actionname = thoughtDict[:Action_name]
actioninput = thoughtDict[:Action_input]
actionname = thoughtDict[:action_name]
actioninput = thoughtDict[:action_input]
# map action and input() to llm function
response =
@@ -1020,131 +992,6 @@ function think(a::T)::NamedTuple{(:actionname, :result), Tuple{String, String}}
end
""" Force to think and check inventory
"""
function forceInventoryCheck(a::T)::NamedTuple{(:actionname, :result), Tuple{String, String}} where {T<:agent}
println("--> forceInventoryCheck()")
thoughtDict = thinkCheckInventory(a)
actionname = thoughtDict[:Action_name]
actioninput = thoughtDict[:Action_input]
# map action and input() to llm function
response =
if actionname == "CHECKINVENTORY"
checkinventory(a, actioninput)
else
error("undefined LLM function. Requesting $actionname")
end
# this section allow LLM functions above to have different return values.
result = haskey(response, :result) ? response[:result] : nothing
select = haskey(response, :select) ? response[:select] : nothing
reward::Integer = haskey(response, :reward) ? response[:reward] : 0
isterminal::Bool = haskey(response, :isterminal) ? response[:isterminal] : false
errormsg::Union{AbstractString, Nothing} = haskey(response, :errormsg) ? response[:errormsg] : nothing
success::Bool = haskey(response, :success) ? response[:success] : false
return (actionname=actionname, result=result)
end
function thinkCheckInventory(a::T)::Dict{Symbol, Any} where {T<:agent}
systemmsg =
"""
You are a helpful sommelier working for a wine store.
Your task is to help the user choose the best wine that match the user preferences from your inventory.
Definitions:
- observation: result of the preceding immediate action.
At each round of conversation, the user will give you the current situation:
Context: ...
Your earlier conversation with the user: ...
You must follow the following guidelines:
- Check inventory immediately based on what you know about the user.
You should then respond to the user with interleaving Thought, Plan, Action and Observation:
- thought:
1) State your reasoning about the current situation.
- plan: Based on the current situation, state a complete plan to complete the task. Be specific.
- action_name (Must be aligned with your plan): Can be one of the following functions:
1) CHECKINVENTORY[query], which you can use to check info about wine in your inventory. "query" is a search term in verbal English.
Good query example: black car with a stereo, 200 mile range and an electric motor.
Good query example: How many car brand are from Asia?
- Action_input: input to the action
You should only respond in format as described below:
thought: ...
plan: ...
action_name: ...
action_input: ...
Let's begin!
"""
usermsg =
"""
Context: None
Your earlier conversation with the user: $(vectorOfDictToText(a.chathistory))
"""
_prompt =
[
Dict(:name=> "system", :text=> systemmsg),
Dict(:name=> "user", :text=> usermsg)
]
# put in model format
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct")
prompt *=
"""
<|start_header_id|>assistant<|end_header_id|>
"""
response = nothing # store for show when error msg show up
for attempt in 1:10
try
response = a.text2textInstructLLM(prompt)
responsedict = GeneralUtils.textToDict(response,
["thought", "plan", "action_name", "action_input"],
rightmarker=":", symbolkey=true)
if responsedict[:action_name] ["CHECKINVENTORY"]
error("decisionMaker didn't use the given functions ", @__LINE__)
end
for i [:thought, :plan, :action_name]
if length(JSON3.write(responsedict[i])) == 0
error("$i is empty ", @__LINE__)
end
end
# check if there are more than 1 key per categories
for i [:thought, :plan, :action_name, :action_input]
matchkeys = GeneralUtils.findMatchingDictKey(responsedict, i)
if length(matchkeys) > 1
error("DecisionMaker has more than one key per categories")
end
end
return responsedict
catch e
io = IOBuffer()
showerror(io, e)
errorMsg = String(take!(io))
st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
println("")
println("Attempt $attempt. Error occurred: $errorMsg\n$st")
println("")
end
end
error("DecisionMaker failed to generate a thought ", response)
end
"""
@@ -1202,7 +1049,7 @@ function generatechat(memory::Dict, chathistory::Vector, text2textInstructLLM::F
"""
context =
if length(memory[:shortmem]) > 0 #[WORKING] add with number order 1), 2)
if length(memory[:shortmem]) > 0
vectorOfDictToText(memory[:shortmem], withkey=false)
else
""
@@ -1237,7 +1084,7 @@ function generatechat(memory::Dict, chathistory::Vector, text2textInstructLLM::F
try
response = text2textInstructLLM(prompt)
responsedict = GeneralUtils.textToDict(response,["Mentioning_wine", "Chat"],
rightmarker=":", symbolkey=true)
rightmarker=":", symbolkey=true, lowercasekey=true)
for i [:Chat]
if length(JSON3.write(responsedict[i])) == 0
@@ -1264,7 +1111,12 @@ function generatechat(memory::Dict, chathistory::Vector, text2textInstructLLM::F
# check if LLM recommend wine before checking inventory
isMemEmpty = isempty(memory[:shortmem])
if occursin("Yes", responsedict[:Mentioning_wine]) && isMemEmpty
if occursin("Yes", responsedict[:mentioning_wine]) && isMemEmpty
errornote = "Note: You can't recommend wines yet. You must check your inventory before recommending wine to the user."
error( "You must check your inventory before recommending wine")
elseif occursin("(check", chatresponse) || occursin("*check", chatresponse) ||
occursin("inventory)", chatresponse) || occursin("inventory*", chatresponse)
errornote = "Note: You can't recommend wines yet. You must check your inventory before recommending wine to the user."
error( "You must check your inventory before recommending wine")
else
@@ -1272,7 +1124,7 @@ function generatechat(memory::Dict, chathistory::Vector, text2textInstructLLM::F
end
memory[:CHATBOX] = "" # delete content because it no longer used.
delete!(responsedict, :Mentioning_wine)
delete!(responsedict, :mentioning_wine)
result = responsedict[:Chat]
return result
@@ -1452,7 +1304,7 @@ function generatequestion(a, text2textInstructLLM::Function; recent=nothing)::St
# response = string(split(response, "Please")[1]) # LLM usually add comments which is no need.
responsedict = GeneralUtils.textToDict(response,
["Understanding", "Q1", "Note"],
rightmarker=":", symbolkey=true)
rightmarker=":", symbolkey=true, lowercasekey=true)
response = "Q1: " * responsedict[:Q1]
println("--> generatequestion ", @__FILE__, " ", @__LINE__)
pprintln(response)
@@ -1739,144 +1591,144 @@ end
function situationtrack(a, text2textInstructLLM::Function)::String
# function situationtrack(a, text2textInstructLLM::Function)::String
systemmsg =
"""
You are a helpful assistant acting as a polite, website-based sommelier for an online wine store.
# systemmsg =
# """
# You are a helpful assistant acting as a polite, website-based sommelier for an online wine store.
Sommelier's general workflow includes:
1) Greet the user and introduce yourself.
2) Understand the user's needs.
3) Looking for the wines that match user's needs in the database.
4) Introduce the wines to the user.
5) Thanks the user when they are done choosing wines and invite them to comeback next time.
# Sommelier's general workflow includes:
# 1) Greet the user and introduce yourself.
# 2) Understand the user's needs.
# 3) Looking for the wines that match user's needs in the database.
# 4) Introduce the wines to the user.
# 5) Thanks the user when they are done choosing wines and invite them to comeback next time.
Your goal includes:
1) Help the user select the best wines from your inventory that align with the user's preferences.
# Your goal includes:
# 1) Help the user select the best wines from your inventory that align with the user's preferences.
Your responsibility includes:
1) Ask yourself specifically about how you are progressing towards the goal.
# Your responsibility includes:
# 1) Ask yourself specifically about how you are progressing towards the goal.
At each round of conversation, you will be given the current situation:
Your conversation with the user: ...
Context: ...
# At each round of conversation, you will be given the current situation:
# Your conversation with the user: ...
# Context: ...
You must follow the following guidelines:
- Your question should be specific, self-contained and not require any additional context.
- Do not generate any question or comments at the end.
# You must follow the following guidelines:
# - Your question should be specific, self-contained and not require any additional context.
# - Do not generate any question or comments at the end.
You should follow the following guidelines:
- Focus on the latest event.
# You should follow the following guidelines:
# - Focus on the latest event.
You should then respond to the user with:
1) Understanding: State your understanding about the current situation
2) Q: Given the situation, "ask yourself" at least five, but no more than ten, questions.
3) A: Given the situation, "answer to yourself" the best you can
4) Note: Additional info you want to say. Otherwise, "NA"
# You should then respond to the user with:
# 1) Understanding: State your understanding about the current situation
# 2) Q: Given the situation, "ask yourself" at least five, but no more than ten, questions.
# 3) A: Given the situation, "answer to yourself" the best you can
# 4) Note: Additional info you want to say. Otherwise, "NA"
You must only respond in format as described below:
Understanding: ...
Q1: ...
A1: ...
Q2: ...
A2: ...
Q3: ...
A3: ...
...
Note: ...
# You must only respond in format as described below:
# Understanding: ...
# Q1: ...
# A1: ...
# Q2: ...
# A2: ...
# Q3: ...
# A3: ...
# ...
# Note: ...
Here are some examples:
Q: Where am I in the workflow?
A: According to the situation, ...
# Here are some examples:
# Q: Where am I in the workflow?
# A: According to the situation, ...
Q: Am I greeting the user and introducing myself?
A: According to the situation, no.
# Q: Am I greeting the user and introducing myself?
# A: According to the situation, no.
Q: Did the user tell me what they like?
A: According to the situation, no. We are just starting the conversation.
# Q: Did the user tell me what they like?
# A: According to the situation, no. We are just starting the conversation.
Q: What do I know about the user?
A: According to the situation, …
# Q: What do I know about the user?
# A: According to the situation, …
Q: Have I searched the database yet?
A: According to the situation, no. I need more information.
# Q: Have I searched the database yet?
# A: According to the situation, no. I need more information.
Q: Did I introduce the coffee blend varieties to the user yet?
A: According to the situation, no, I didn't because I have not searched the database yet.
# Q: Did I introduce the coffee blend varieties to the user yet?
# A: According to the situation, no, I didn't because I have not searched the database yet.
Q: What did I find in the database?
A: According to the situation, I found the following …
# Q: What did I find in the database?
# A: According to the situation, I found the following …
Let's begin!
"""
# Let's begin!
# """
timeline = ""
for (i, event) in enumerate(a.memory[:events])
if event[:outcome] === nothing
timeline *= "$i) $(event[:subject])> $(event[:action_or_dialogue])\n"
else
timeline *= "$i) $(event[:subject])> $(event[:action_or_dialogue]) $(event[:outcome])\n"
end
end
# timeline = ""
# for (i, event) in enumerate(a.memory[:events])
# if event[:outcome] === nothing
# timeline *= "$i) $(event[:subject])> $(event[:action_or_dialogue])\n"
# else
# timeline *= "$i) $(event[:subject])> $(event[:action_or_dialogue]) $(event[:outcome])\n"
# end
# end
context =
if length(a.memory[:shortmem]) > 0
vectorOfDictToText(a.memory[:shortmem], withkey=false)
else
""
end
chathistory = vectorOfDictToText(a.chathistory)
errornote = ""
response = nothing # store for show when error msg show up
# context =
# if length(a.memory[:shortmem]) > 0
# vectorOfDictToText(a.memory[:shortmem], withkey=false)
# else
# ""
# end
# chathistory = vectorOfDictToText(a.chathistory)
# errornote = ""
# response = nothing # store for show when error msg show up
for attempt in 1:10
usermsg =
"""
Events timeline: $timeline
$context
$errornote
"""
# for attempt in 1:10
# usermsg =
# """
# Events timeline: $timeline
# $context
# $errornote
# """
_prompt =
[
Dict(:name=> "system", :text=> systemmsg),
Dict(:name=> "user", :text=> usermsg)
]
# _prompt =
# [
# Dict(:name=> "system", :text=> systemmsg),
# Dict(:name=> "user", :text=> usermsg)
# ]
# put in model format
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct")
prompt *=
"""
<|start_header_id|>assistant<|end_header_id|>
"""
# # put in model format
# prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct")
# prompt *=
# """
# <|start_header_id|>assistant<|end_header_id|>
# """
try
response = text2textInstructLLM(prompt)
q_number = count("Q", response)
if q_number < 3
error("too few questions only $q_number questions are generated ", @__FILE__, " ", @__LINE__)
end
# response = string(split(response, "Please")[1]) # LLM usually add comments which is no need.
responsedict = GeneralUtils.textToDict(response,
["Understanding", "Q1", "Note"],
rightmarker=":", symbolkey=true)
response = "Q1: " * responsedict[:Q1]
println("--> situationtrack ", @__FILE__, " ", @__LINE__)
pprintln(Dict(responsedict))
return response
catch e
io = IOBuffer()
showerror(io, e)
errorMsg = String(take!(io))
st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
println("")
println("Attempt $attempt. Error occurred: $errorMsg\n$st")
println("")
end
end
error("situationtrack failed to generate a thought ", response)
end
# try
# response = text2textInstructLLM(prompt)
# q_number = count("Q", response)
# if q_number < 3
# error("too few questions only $q_number questions are generated ", @__FILE__, " ", @__LINE__)
# end
# # response = string(split(response, "Please")[1]) # LLM usually add comments which is no need.
# responsedict = GeneralUtils.textToDict(response,
# ["Understanding", "Q1", "Note"],
# rightmarker=":", symbolkey=true)
# response = "Q1: " * responsedict[:Q1]
# println("--> situationtrack ", @__FILE__, " ", @__LINE__)
# pprintln(Dict(responsedict))
# return response
# catch e
# io = IOBuffer()
# showerror(io, e)
# errorMsg = String(take!(io))
# st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
# println("")
# println("Attempt $attempt. Error occurred: $errorMsg\n$st")
# println("")
# end
# end
# error("situationtrack failed to generate a thought ", response)
# end