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

View File

@@ -149,7 +149,7 @@ function sommelier(
:activeplan => Dict{Symbol, Any}(), # current using plan :activeplan => Dict{Symbol, Any}(), # current using plan
:currenttrajectory=> Dict{Symbol, Any}(), # store question, thought, action, observation, ... :currenttrajectory=> Dict{Symbol, Any}(), # store question, thought, action, observation, ...
) ),
mctsWorkDict::Dict{Symbol, Any} = Dict{Symbol, Any}() 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) response = a.text2textInstructLLM(prompt)
responsedict = GeneralUtils.textToDict(response, responsedict = GeneralUtils.textToDict(response,
["Understanding", "Reasoning", "Plan", "Action_name", "Action_input", "Mentioning_wine"], ["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" errornote = "You must use the given functions"
error("You must use the given functions ", @__FILE__, " ", @__LINE__) error("You must use the given functions ", @__FILE__, " ", @__LINE__)
end end
for i [:Understanding, :Plan, :Action_name] for i [:understanding, :plan, :action_name]
if length(responsedict[i]) == 0 if length(responsedict[i]) == 0
error("$i is empty ", @__FILE__, " ", @__LINE__) error("$i is empty ", @__FILE__, " ", @__LINE__)
end end
end end
# check if there are more than 1 key per categories # 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) matchkeys = GeneralUtils.findMatchingDictKey(responsedict, i)
if length(matchkeys) > 1 if length(matchkeys) > 1
error("DecisionMaker has more than one key per categories") 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 # check if LLM recommend wine before checking inventory
isMemEmpty = isempty(a.memory[:shortmem]) isMemEmpty = isempty(a.memory[:shortmem])
if occursin("Yes", responsedict[:Mentioning_wine]) && isMemEmpty && if occursin("Yes", responsedict[:mentioning_wine]) && isMemEmpty &&
responsedict[:Action_name] != "CHECKINVENTORY" responsedict[:action_name] != "CHECKINVENTORY"
errornote = "Note: You can't recommend wines yet. You must check your inventory before recommending wine to the user." 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") error( "You can't recommend wines yet. You must check your inventory before recommending wines")
elseif responsedict[:Action_name] == "PRESENTBOX" && isMemEmpty && elseif responsedict[:action_name] == "PRESENTBOX" && isMemEmpty &&
responsedict[:Action_name] != "CHECKINVENTORY" responsedict[:action_name] != "CHECKINVENTORY"
errornote = "Note: You can't recommend wines yet. You must check your inventory before recommending wine to the user." 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") 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 = "" errornote = ""
end end
delete!(responsedict, :Mentioning_wine) delete!(responsedict, :mentioning_wine)
return responsedict return responsedict
catch e catch e
@@ -903,23 +903,6 @@ function conversation(a::T, userinput::Dict) where {T<:agent}
# thought will be added to chat model via context # thought will be added to chat model via context
chatresponse = generatechat(a.memory, a.chathistory, a.text2textInstructLLM) 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) addNewMessage(a, "assistant", chatresponse)
push!(a.memory[:events], push!(a.memory[:events],
@@ -954,22 +937,11 @@ function think(a::T)::NamedTuple{(:actionname, :result), Tuple{String, String}}
a.memory[:recap] = generateSituationReport(a, a.text2textInstructLLM; skiprecent=5) a.memory[:recap] = generateSituationReport(a, a.text2textInstructLLM; skiprecent=5)
a.memory[:QandA] = generatequestion(a, a.text2textInstructLLM; recent=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) thoughtDict = decisionMaker(a; recent=5)
actionname = thoughtDict[:Action_name] actionname = thoughtDict[:action_name]
actioninput = thoughtDict[:Action_input] actioninput = thoughtDict[:action_input]
# map action and input() to llm function # map action and input() to llm function
response = response =
@@ -1020,131 +992,6 @@ function think(a::T)::NamedTuple{(:actionname, :result), Tuple{String, String}}
end 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 = context =
if length(memory[:shortmem]) > 0 #[WORKING] add with number order 1), 2) if length(memory[:shortmem]) > 0
vectorOfDictToText(memory[:shortmem], withkey=false) vectorOfDictToText(memory[:shortmem], withkey=false)
else else
"" ""
@@ -1237,7 +1084,7 @@ function generatechat(memory::Dict, chathistory::Vector, text2textInstructLLM::F
try try
response = text2textInstructLLM(prompt) response = text2textInstructLLM(prompt)
responsedict = GeneralUtils.textToDict(response,["Mentioning_wine", "Chat"], responsedict = GeneralUtils.textToDict(response,["Mentioning_wine", "Chat"],
rightmarker=":", symbolkey=true) rightmarker=":", symbolkey=true, lowercasekey=true)
for i [:Chat] for i [:Chat]
if length(JSON3.write(responsedict[i])) == 0 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 # check if LLM recommend wine before checking inventory
isMemEmpty = isempty(memory[:shortmem]) 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." 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") error( "You must check your inventory before recommending wine")
else else
@@ -1272,7 +1124,7 @@ function generatechat(memory::Dict, chathistory::Vector, text2textInstructLLM::F
end end
memory[:CHATBOX] = "" # delete content because it no longer used. memory[:CHATBOX] = "" # delete content because it no longer used.
delete!(responsedict, :Mentioning_wine) delete!(responsedict, :mentioning_wine)
result = responsedict[:Chat] result = responsedict[:Chat]
return result 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. # response = string(split(response, "Please")[1]) # LLM usually add comments which is no need.
responsedict = GeneralUtils.textToDict(response, responsedict = GeneralUtils.textToDict(response,
["Understanding", "Q1", "Note"], ["Understanding", "Q1", "Note"],
rightmarker=":", symbolkey=true) rightmarker=":", symbolkey=true, lowercasekey=true)
response = "Q1: " * responsedict[:Q1] response = "Q1: " * responsedict[:Q1]
println("--> generatequestion ", @__FILE__, " ", @__LINE__) println("--> generatequestion ", @__FILE__, " ", @__LINE__)
pprintln(response) pprintln(response)
@@ -1739,144 +1591,144 @@ end
function situationtrack(a, text2textInstructLLM::Function)::String # function situationtrack(a, text2textInstructLLM::Function)::String
systemmsg = # systemmsg =
""" # """
You are a helpful assistant acting as a polite, website-based sommelier for an online wine store. # You are a helpful assistant acting as a polite, website-based sommelier for an online wine store.
Sommelier's general workflow includes: # Sommelier's general workflow includes:
1) Greet the user and introduce yourself. # 1) Greet the user and introduce yourself.
2) Understand the user's needs. # 2) Understand the user's needs.
3) Looking for the wines that match user's needs in the database. # 3) Looking for the wines that match user's needs in the database.
4) Introduce the wines to the user. # 4) Introduce the wines to the user.
5) Thanks the user when they are done choosing wines and invite them to comeback next time. # 5) Thanks the user when they are done choosing wines and invite them to comeback next time.
Your goal includes: # Your goal includes:
1) Help the user select the best wines from your inventory that align with the user's preferences. # 1) Help the user select the best wines from your inventory that align with the user's preferences.
Your responsibility includes: # Your responsibility includes:
1) Ask yourself specifically about how you are progressing towards the goal. # 1) Ask yourself specifically about how you are progressing towards the goal.
At each round of conversation, you will be given the current situation: # At each round of conversation, you will be given the current situation:
Your conversation with the user: ... # Your conversation with the user: ...
Context: ... # Context: ...
You must follow the following guidelines: # You must follow the following guidelines:
- Your question should be specific, self-contained and not require any additional context. # - Your question should be specific, self-contained and not require any additional context.
- Do not generate any question or comments at the end. # - Do not generate any question or comments at the end.
You should follow the following guidelines: # You should follow the following guidelines:
- Focus on the latest event. # - Focus on the latest event.
You should then respond to the user with: # You should then respond to the user with:
1) Understanding: State your understanding about the current situation # 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. # 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 # 3) A: Given the situation, "answer to yourself" the best you can
4) Note: Additional info you want to say. Otherwise, "NA" # 4) Note: Additional info you want to say. Otherwise, "NA"
You must only respond in format as described below: # You must only respond in format as described below:
Understanding: ... # Understanding: ...
Q1: ... # Q1: ...
A1: ... # A1: ...
Q2: ... # Q2: ...
A2: ... # A2: ...
Q3: ... # Q3: ...
A3: ... # A3: ...
... # ...
Note: ... # Note: ...
Here are some examples: # Here are some examples:
Q: Where am I in the workflow? # Q: Where am I in the workflow?
A: According to the situation, ... # A: According to the situation, ...
Q: Am I greeting the user and introducing myself? # Q: Am I greeting the user and introducing myself?
A: According to the situation, no. # A: According to the situation, no.
Q: Did the user tell me what they like? # Q: Did the user tell me what they like?
A: According to the situation, no. We are just starting the conversation. # A: According to the situation, no. We are just starting the conversation.
Q: What do I know about the user? # Q: What do I know about the user?
A: According to the situation, … # A: According to the situation, …
Q: Have I searched the database yet? # Q: Have I searched the database yet?
A: According to the situation, no. I need more information. # A: According to the situation, no. I need more information.
Q: Did I introduce the coffee blend varieties to the user 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. # 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? # Q: What did I find in the database?
A: According to the situation, I found the following … # A: According to the situation, I found the following …
Let's begin! # Let's begin!
""" # """
timeline = "" # timeline = ""
for (i, event) in enumerate(a.memory[:events]) # for (i, event) in enumerate(a.memory[:events])
if event[:outcome] === nothing # if event[:outcome] === nothing
timeline *= "$i) $(event[:subject])> $(event[:action_or_dialogue])\n" # timeline *= "$i) $(event[:subject])> $(event[:action_or_dialogue])\n"
else # else
timeline *= "$i) $(event[:subject])> $(event[:action_or_dialogue]) $(event[:outcome])\n" # timeline *= "$i) $(event[:subject])> $(event[:action_or_dialogue]) $(event[:outcome])\n"
end # end
end # end
context = # context =
if length(a.memory[:shortmem]) > 0 # if length(a.memory[:shortmem]) > 0
vectorOfDictToText(a.memory[:shortmem], withkey=false) # vectorOfDictToText(a.memory[:shortmem], withkey=false)
else # else
"" # ""
end # end
chathistory = vectorOfDictToText(a.chathistory) # chathistory = vectorOfDictToText(a.chathistory)
errornote = "" # errornote = ""
response = nothing # store for show when error msg show up # response = nothing # store for show when error msg show up
for attempt in 1:10 # for attempt in 1:10
usermsg = # usermsg =
""" # """
Events timeline: $timeline # Events timeline: $timeline
$context # $context
$errornote # $errornote
""" # """
_prompt = # _prompt =
[ # [
Dict(:name=> "system", :text=> systemmsg), # Dict(:name=> "system", :text=> systemmsg),
Dict(:name=> "user", :text=> usermsg) # Dict(:name=> "user", :text=> usermsg)
] # ]
# put in model format # # put in model format
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct") # prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct")
prompt *= # prompt *=
""" # """
<|start_header_id|>assistant<|end_header_id|> # <|start_header_id|>assistant<|end_header_id|>
""" # """
try # try
response = text2textInstructLLM(prompt) # response = text2textInstructLLM(prompt)
q_number = count("Q", response) # q_number = count("Q", response)
if q_number < 3 # if q_number < 3
error("too few questions only $q_number questions are generated ", @__FILE__, " ", @__LINE__) # error("too few questions only $q_number questions are generated ", @__FILE__, " ", @__LINE__)
end # end
# response = string(split(response, "Please")[1]) # LLM usually add comments which is no need. # # response = string(split(response, "Please")[1]) # LLM usually add comments which is no need.
responsedict = GeneralUtils.textToDict(response, # responsedict = GeneralUtils.textToDict(response,
["Understanding", "Q1", "Note"], # ["Understanding", "Q1", "Note"],
rightmarker=":", symbolkey=true) # rightmarker=":", symbolkey=true)
response = "Q1: " * responsedict[:Q1] # response = "Q1: " * responsedict[:Q1]
println("--> situationtrack ", @__FILE__, " ", @__LINE__) # println("--> situationtrack ", @__FILE__, " ", @__LINE__)
pprintln(Dict(responsedict)) # pprintln(Dict(responsedict))
return response # return response
catch e # catch e
io = IOBuffer() # io = IOBuffer()
showerror(io, e) # showerror(io, e)
errorMsg = String(take!(io)) # errorMsg = String(take!(io))
st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace())) # st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
println("") # println("")
println("Attempt $attempt. Error occurred: $errorMsg\n$st") # println("Attempt $attempt. Error occurred: $errorMsg\n$st")
println("") # println("")
end # end
end # end
error("situationtrack failed to generate a thought ", response) # error("situationtrack failed to generate a thought ", response)
end # end