diff --git a/src/interface.jl b/src/interface.jl
index 2c5e2b7..8f02f6b 100755
--- a/src/interface.jl
+++ b/src/interface.jl
@@ -308,100 +308,6 @@ function updatePlan(a::agentReflex)
end
-# function selfAwareness(a::agentReflex)
-
-# getonlykeys = ["Actinput", "Obs"]
-# worknoplan = similar(a.memory[:shortterm])
-# for (k, v) in a.memory[:shortterm]
-# count = 0
-# for i in getonlykeys
-# if occursin(i, k)
-# count += 1
-# end
-# end
-# if count != 0
-# worknoplan[k] = v
-# end
-# end
-
-# work = dictToString(worknoplan)
-
-# aboutYourself =
-# """
-# Your name is $(a.agentName)
-# $(a.roles[a.role])
-
-# """
-
-# prompt =
-# """
-# <|system|>
-#
-# $aboutYourself
-# $(a.roleSpecificInstruction[a.role])
-#
-#
-# $work
-#
-#
-# $(JSON3.write(a.memory[:keyword]))
-#
-#
-# Use the following format strictly:
-# Info extraction: repeat all important info from the latest observed result thoroughly
-# Info mapping: based on extracted info, explicitly state what each info could match which keyword memory's key
-# Info matching: using JSON format, what key in my memory matches which info
-#
-
-#
-#
-# The user wants to buy an electric SUV car under 20000 dollars.
-#
-#
-# {"car type": null, "color": null, "financing": null}
-#
-# Info extraction:
-# - The user is buying an electric SUV car.
-# Info mapping:
-# - SUV could matches "car type" key
-# - electric could matches "engine type" key
-# Info matching: {"car type": "SUV", "engine type": "electric motor", "color": null, "financing": null}
-#
-#
-# <|assistant|>
-# Info extraction:
-# """
-# response = sendReceivePrompt(a, prompt, max_tokens=1024, temperature=0.2, timeout=180,
-# stopword=["/n/n", "END", "End", "Obs", "<|", ""])
-# response = split(response, "<|")[1]
-# response = split(response, "")[1]
-# response = "Info extraction:" * response
-
-# println("")
-# @show selfaware_1 = response
-
-# headerToDetect = ["Info extraction:", "Info mapping:", "Info matching:", "Actinput"]
-# headers = detectCharacters(response, headerToDetect)
-
-# # headers[1:2] is for when LLM generate more than a paire of "Info extraction" and "Info matching", discard the rest
-# chunkedtext = chunktext(response, headers[1:3])
-# println("")
-# _infomatch = chunkedtext["Info matching:"]
-# _infomatch = GeneralUtils.getStringBetweenCharacters(_infomatch, '{', '}', endCharLocation="next")
-# infomatch = copy(JSON3.read(_infomatch))
-
-# println("")
-# @show chunkedtext
-
-# keywordMemoryUpdate!(a.memory[:keyword], infomatch)
-
-# response = "What I know about user:" * JSON3.write(a.memory[:keyword]) # * response
-# println("")
-# @show selfaware_2 = response
-
-
-# return response
-# end
function selfAwareness(a::agentReflex)
@@ -433,7 +339,7 @@ function selfAwareness(a::agentReflex)
$(a.roles[a.role])
"""
- #WORKING may be I need to use "- $k is $v" because LLM skip the key for sweetness
+
prompt =
"""
@@ -514,6 +420,189 @@ function selfAwareness(a::agentReflex)
return response
end
+function sentenceToKeywordMemory(a::agentReflex)
+
+ getonlykeys = ["Actinput", "Obs"]
+ worknoplan = similar(a.memory[:shortterm])
+ worklength = length(a.memory[:shortterm])
+ for (i, (k, v)) in enumerate(a.memory[:shortterm])
+ if i >= worklength - 1
+ count = 0
+ for i in getonlykeys
+ if occursin(i, k)
+ count += 1
+ end
+ end
+ if count != 0
+ worknoplan[k] = v
+ end
+ end
+ end
+
+ println("")
+ @show worknoplan
+
+ work = dictToString(worknoplan)
+
+ aboutYourself =
+ """
+ Your name is $(a.agentName)
+ $(a.roles[a.role])
+
+ """
+
+ prompt =
+ """
+
+ <|system|>
+
+ $aboutYourself
+ $(a.roleSpecificInstruction[a.role])
+
+
+ Use the following format strictly:
+ Info extraction: repeat all important info from the latest observed result thoroughly
+ Info mapping: based on extracted info, explicitly state what each info could match which keyword memory's key
+ Info matching: using JSON format, what key in my memory matches which info
+
+ |system|>
+
+
+ The user wants to buy an electric SUV car under 20000 dollars.
+
+
+ {\"car type\": null, \"engine type\": null, \"price\": null, \"color\": null, \"financing\": null}
+
+ <|assistant|>
+ Info extraction:
+ - The user is buying an electric SUV car.
+ - price is under 20000 dollars
+ Info mapping:
+ - "SUV" could matches "car type" key
+ - "electric" could matches "engine type" key
+ - "under 20000 dollars" could match "price" key
+ Info matching: {\"car type\": \"SUV\", \"engine type\": \"electric motor\", \"price\": \"under 20000\", \"color\": null, \"financing\": null}
+ |assistant|>
+
+
+
+ $work
+
+
+ $(JSON3.write(a.memory[:keyword]))
+
+ <|assistant|>
+ Info extraction:
+ """
+ response = sendReceivePrompt(a, prompt, max_tokens=1024, temperature=0.2, timeout=180,
+ stopword=["/n/n", "END", "End", "Obs", "<|", ""])
+ response = split(response, "<|")[1]
+ response = split(response, "")[1]
+ response = split(response, "|assistant|>")[1]
+ response = "Info extraction:" * response
+
+ println("")
+ @show selfaware_1 = response
+
+ headerToDetect = ["Info extraction:", "Info mapping:", "Info matching:", "Actinput"]
+ headers = detectCharacters(response, headerToDetect)
+
+ # headers[1:2] is for when LLM generate more than a paire of "Info extraction" and "Info matching", discard the rest
+ chunkedtext = chunktext(response, headers[1:3])
+ println("")
+ _infomatch = chunkedtext["Info matching:"]
+ _infomatch = GeneralUtils.getStringBetweenCharacters(_infomatch, '{', '}', endCharLocation="end")
+ infomatch = GeneralUtils.JSON3read_stringKey(_infomatch)
+ # infomatch = copy(JSON3.read(_infomatch))
+
+ println("")
+ @show chunkedtext
+
+ println("")
+ @show infomatch
+
+ keywordMemoryUpdate!(a.memory[:keyword], infomatch)
+end
+
+function keywordMemoryToPlanMatching(a::agentReflex)
+
+ aboutYourself =
+ """
+ Your name is $(a.agentName)
+ $(a.roles[a.role])
+
+ """
+
+ prompt =
+ """
+
+ <|system|>
+
+ $aboutYourself
+ $(a.roleSpecificInstruction[a.role])
+
+
+ Use the following format strictly:
+ Info mapping: explicitly state what each step of the plan could match which keyword memory's key
+ Info matching: using JSON format, what key in my memory matches which info
+
+ |system|>
+
+
+ 1. ask the user for car type,
+ 2. ask the user for color
+
+
+ {\"car type\": "SUV", \"color\": null}
+
+ <|assistant|>
+ Info mapping:
+ -In step 1 of the plan, I need to ask the user about the car type. From user info, the car type is "SUV". Therefore this step is done.
+ -In step 2 of the plan, I need to ask the user about the color . From user info, the color is null. Therefore this step is not done yet and I'll need to do this step.
+ |assistant|>
+
+
+
+ $work
+
+
+ $(JSON3.write(a.memory[:keyword]))
+
+ <|assistant|>
+ Info mapping:
+ """
+ response = sendReceivePrompt(a, prompt, max_tokens=1024, temperature=0.2, timeout=180,
+ stopword=["/n/n", "END", "End", "Obs", "<|", ""])
+ response = split(response, "<|")[1]
+ response = split(response, "")[1]
+ response = split(response, "|assistant|>")[1]
+ response = "Info mapping:" * response
+
+ println("")
+ @show keywordMemoryToPlanMatching = response
+
+ error(1111)
+
+ headerToDetect = ["Info extraction:", "Info mapping:", "Info matching:", "Actinput"]
+ headers = detectCharacters(response, headerToDetect)
+
+ # headers[1:2] is for when LLM generate more than a paire of "Info extraction" and "Info matching", discard the rest
+ chunkedtext = chunktext(response, headers[1:3])
+ println("")
+ _infomatch = chunkedtext["Info matching:"]
+ _infomatch = GeneralUtils.getStringBetweenCharacters(_infomatch, '{', '}', endCharLocation="end")
+ infomatch = GeneralUtils.JSON3read_stringKey(_infomatch)
+ # infomatch = copy(JSON3.read(_infomatch))
+
+ println("")
+ @show chunkedtext
+
+ println("")
+ @show infomatch
+
+ keywordMemoryUpdate!(a.memory[:keyword], infomatch)
+end
+
# function actor_mistral_openorca(a::agentReflex, selfaware=nothing)
# getonlykeys = ["Actinput", "Obs"]
# worknoplan = similar(a.memory[:shortterm])
@@ -844,37 +933,19 @@ function actor_mistral_openorca(a::agentReflex, selfaware=nothing)
Use the following format:
- Thought: based on what you know about the user, where are you at according to the plan? what to do next?. (PS. 1. let's think only one thing at a time. 2. pay attention to correct numeral calculation and commonsense.)
+ Thought: based on your user info, think about what to do to next according to the plan. (PS. 1. let's think only one thing at a time. 2. pay attention to correct numeral calculation and commonsense.)
Act: based on your thought what action to choose?, must be one of [{toolnames}].
Actinput: your input to the action using JSON format (pay attention to the tool's input)
Obs: observed result of the action
|system|>
-
-
- I'll ask the user for car type, brand, price, color, financing method and luxury level before I'll give them any advice.
-
-
- - Car type is SUV
- - Brand is Lexus
- - Price is 20k dollar
- - No info on the car color yet
- - No info on the financing method yet
- - Luxury level is high
-
- <|assistant|>
- Thought: after checking what I know about the user against my plan, I still don't know the color and financing method yet. Next, I need to know what color the user like.
- Act: askbox
- Actinput:
- |assistant|>
-
$(a.memory[:shortterm]["Plan 1:"])
-
- $keywordmemory)
-
+
+ $keywordmemory
+
<|assistant|>
Thought:
"""
@@ -890,7 +961,7 @@ function actor_mistral_openorca(a::agentReflex, selfaware=nothing)
while true # while Thought or Act is empty, run actor again
- response = sendReceivePrompt(a, prompt, max_tokens=1024, temperature=0.4, timeout=300,
+ response = sendReceivePrompt(a, prompt, max_tokens=1024, temperature=0.0, timeout=300,
stopword=["Thought:", "Obs:", "<|system|>", "", "<|end|>"],
seed=rand(1000000:2000000))
println("")
@@ -1246,6 +1317,7 @@ function actor(a::agentReflex)
selfaware = nothing
if length(a.memory[:shortterm]) > 2 # must have User:, Plan:, Thought:, Act:, Actinput: already
selfaware = selfAwareness(a)
+ # result = keywordMemoryToPlanMatching(a)
end
actorResult = actor_mistral_openorca(a, selfaware)
diff --git a/src/llmfunction.jl b/src/llmfunction.jl
index f041c99..6108ecf 100644
--- a/src/llmfunction.jl
+++ b/src/llmfunction.jl
@@ -174,29 +174,29 @@ function winestock(a::agentReflex, input::NamedTuple)
Dessert = table for wine type "dessert"
Fortified = table for wine type "fortified"
Intensity level:
- intensity = 1, light bodied
- intensity = 2, semi-light bodied
- intensity = 3, medium bodied
- intensity = 4, semi-full bodied
- intensity = 5, full bodied
+ light bodied = 1
+ semi-light bodied = 2
+ medium bodied = 3
+ semi-full bodied = 4
+ full bodied = 5
Sweetness level:
- sweetness = 1, dry
- sweetness = 2, off-dry
- sweetness = 3, semi-sweet
- sweetness = 4, sweet
- sweetness = 5, very sweet
+ dry = 1
+ off-dry = 2
+ semi-sweet = 3
+ sweet = 4
+ very sweet = 5
Tannin level:
- tannin = 1, low tannin
- tannin = 2, semi-low tannin
- tannin = 3, medium tannin
- tannin = 4, semi-high tannin
- tannin = 5, high tannin
+ low tannin = 1
+ semi-low tannin = 2
+ medium tannin = 3
+ semi-high tannin = 4
+ high tannin = 4
Acidity level:
- acidity = 1, low acidity
- acidity = 2, semi-low acidity
- acidity = 3, medium acidity
- acidity = 4, semi-high acidity
- acidity = 5, high acidity
+ low acidity = 1
+ semi-low acidity = 2
+ medium acidity = 3
+ semi-high acidity = 4
+ high acidity = 5
Write a specific SQL command from a query using a conversion table
@@ -270,15 +270,13 @@ function winestock(a::agentReflex, input::NamedTuple)
body = newsql
uri = URI(scheme="http", host="192.168.88.12", port="9010", path="/sql", userinfo="root:root")
r = HTTP.request("POST", uri, ["Accept" => "application/json", "NS"=>"yiem", "DB"=>"Blossom_wines"], body)
- println("")
- @show r
+
a.memory[:r] = r
result = copy(JSON3.read(r.body))
wines = shuffle(result[1][:result]) # shuffle in case there are more than 1 result
- println("")
- @show wines
+
# choose only 2 wines
if length(wines) > 2
@@ -286,6 +284,9 @@ function winestock(a::agentReflex, input::NamedTuple)
wines = wines[1:2]
end
+ println("")
+ @show wines
+
result = nothing
if length(wines) == 0
result =
diff --git a/src/type.jl b/src/type.jl
index 12d8e6f..87e35ef 100644
--- a/src/type.jl
+++ b/src/type.jl
@@ -152,7 +152,7 @@ function agentReflex(
"""
Request the user’s input for the following info initially, and use alternative sources of information only if they are unable to provide it:
- wine price range: ask the user
- - wine type (Rose, White, Red, Rose, Sparkling, Dessert)
+ - wine type (rose, white, red, sparkling, dessert)
- food type that will be served with wine
- wine sweetness level (dry to very sweet)
- wine intensity level (light to full bodied)