use string key for dict

This commit is contained in:
2026-06-25 06:16:30 +07:00
parent f5875dcb61
commit bc81033924
4 changed files with 155 additions and 155 deletions
+104 -104
View File
@@ -23,22 +23,22 @@ using ..util, ..llmfunction
A function that handles communication to LLM service
# Return
- `thoughtDict::Dict{Symbol, Any}`
- `thoughtDict::Dict{String, Any}`
# Example
```jldoctest
julia> using SQLLLM, GeneralUtils, UUIDs, DataStructures, PrettyPrinting
julia> state = Dict(
:isterminal => false,
:lesson => nothing,
:reward => 0,
:evaluation => "None",
:accepted_as_answer => "No",
:thoughtHistory => OrderedDict{Symbol, Any}(:question => "How many wines do you have that can be paired with lamb?"),
:evaluationscore => 0,
:suggestion => "None"
"isterminal" => false,
"lesson" => nothing,
"reward" => 0,
"evaluation" => "None",
"accepted_as_answer" => "No",
"thoughtHistory" => OrderedDict{String, Any}("question" => "How many wines do you have that can be paired with lamb?"),
"evaluationscore" => 0,
"suggestion" => "None"
)
julia> context = Dict(:tablelist=> "None")
julia> context = Dict("tablelist"=> "None")
julia> function text2textInstructLLM(prompt::String)
config = Dict(
:mqttServerInfo => Dict(
@@ -104,7 +104,7 @@ Dict(
"""
function decisionMaker(state::T1, additionalinfo, text2textInstructLLM::Function, llmFormatName::String
; querySQLVectorDBF::Union{T2, Nothing}=nothing, maxattempt=10
)::Dict{Symbol, Any} where {T1<:AbstractDict, T2<:Function}
)::Dict{String, Any} where {T1<:AbstractDict, T2<:Function}
# lessonDict =
# if isfile("lesson.json")
@@ -174,8 +174,8 @@ function decisionMaker(state::T1, additionalinfo, text2textInstructLLM::Function
"""
requiredKeys = [:plan, :action_name, :action_input]
workprogress = ""
for (k, v) in state[:thoughtHistory]
if k [:question]
for (k, v) in state["thoughtHistory"]
if k ["question"]
workprogress *= "$k: $v\n"
end
end
@@ -184,11 +184,11 @@ function decisionMaker(state::T1, additionalinfo, text2textInstructLLM::Function
errornote = "N/A"
# provide similar sql only for the first attempt
similarSQL_ = "None"
if length(state[:thoughtHistory]) == 1
sql, distance = querySQLVectorDBF(state[:thoughtHistory][:question])
similarSQL_ = sql !== nothing ? sql : "None"
end
similarSQL_ = "None"
if length(state["thoughtHistory"]) == 1
sql, distance = querySQLVectorDBF(state["thoughtHistory"]["question"])
similarSQL_ = sql !== nothing ? sql : "None"
end
for attempt in 1:maxattempt
@@ -211,7 +211,7 @@ function decisionMaker(state::T1, additionalinfo, text2textInstructLLM::Function
$workprogress
</progress>
<suggestion> This is your mentor's suggestion for the immediately preceding action and observation
$(state[:suggestion])
$(state["suggestion"])
</suggestion>
P.S. $errornote
</context>
@@ -220,7 +220,7 @@ function decisionMaker(state::T1, additionalinfo, text2textInstructLLM::Function
unformatPrompt =
[
Dict(:name => "system", :text => systemmsg),
Dict(:name => "user", :text => state[:thoughtHistory][:question])
Dict("name" => "user", "text" => state["thoughtHistory"]["question"])
]
# put in model format
@@ -262,31 +262,31 @@ function decisionMaker(state::T1, additionalinfo, text2textInstructLLM::Function
continue
end
delete!(responsedict, :observation)
delete!(responsedict, "observation")
# remove backticks Error occurred: MethodError: no method matching occursin(::String, ::Vector{String})
if occursin("```", responsedict[:action_input])
sql = GeneralUtils.extract_triple_backtick_text(responsedict[:action_input])[1]
if occursin("```", responsedict["action_input"])
sql = GeneralUtils.extract_triple_backtick_text(responsedict["action_input"])[1]
if sql[1:4] == "sql\n"
sql = sql[5:end]
end
sql = split(sql, ';') # some time there are comments in the sql
sql = sql[1] * ';'
responsedict[:action_input] = sql
responsedict["action_input"] = sql
end
toollist = ["TABLEINFO", "RUNSQL"]
if responsedict[:action_name] toollist
if responsedict["action_name"] toollist
errornote = "Your previous attempt has action_name that is not in the tool list"
println("\nERROR SQLLLM decisionMaker(). Attempt $attempt/$maxattempt. $errornote --(not qualify response)--> $(responsedict[:action_name]) ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
println("\nERROR SQLLLM decisionMaker(). Attempt $attempt/$maxattempt. $errornote --(not qualify response)--> $(responsedict["action_name"]) ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
continue
end
for i in toollist
if occursin(i, responsedict[:action_input])
if occursin(i, responsedict["action_input"])
errornote = "Your previous attempt has action_name in action_input which is not allowed"
println("\nERROR SQLLLM decisionMaker(). Attempt $attempt/$maxattempt. $errornote --(not qualify response)--> $(responsedict[:action_input]) ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
println("\nERROR SQLLLM decisionMaker(). Attempt $attempt/$maxattempt. $errornote --(not qualify response)--> $(responsedict["action_input"]) ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
continue
end
end
@@ -303,11 +303,11 @@ function decisionMaker(state::T1, additionalinfo, text2textInstructLLM::Function
pprintln(Dict(responsedict))
# store for later training
responsedict[:thoughthistory] = state[:thoughtHistory]
responsedict[:system] = systemmsg
responsedict[:prompt] = prompt
responsedict[:context] = context
responsedict[:think] = think
responsedict["thoughthistory"] = state["thoughtHistory"]
responsedict["system"] = systemmsg
responsedict["prompt"] = prompt
responsedict["context"] = context
responsedict["think"] = think
# # read sessionId
# sessionid = JSON3.read("/appfolder/app/sessionid.json")
@@ -339,7 +339,7 @@ end
# function decisionMaker(state::T1, context, text2textInstructLLM::Function, llmFormatName::String
# ; querySQLVectorDBF::Union{T2, Nothing}=nothing, maxattempt=10
# )::Dict{Symbol, Any} where {T1<:AbstractDict, T2<:Function}
# )::Dict{String, Any} where {T1<:AbstractDict, T2<:Function}
# # lessonDict =
# # if isfile("lesson.json")
@@ -523,7 +523,7 @@ end
# end
# responsedict = GeneralUtils.textToDict(response, header;
# dictKey=dictkey, symbolkey=true)
# dictKey=dictkey, symbolkey=false)
# delete!(responsedict, :observation)
@@ -653,7 +653,7 @@ function evaluator(state::T1, thoughtDict, text2textInstructLLM::Function, llmFo
dictkey = ["trajectory_evaluation", "answer_evaluation", "accepted_as_answer", "score", "suggestion"]
thoughthistory = ""
for (k, v) in state[:thoughtHistory]
for (k, v) in state["thoughtHistory"]
thoughthistory *= "$k: $v\n"
end
@@ -707,39 +707,39 @@ function evaluator(state::T1, thoughtDict, text2textInstructLLM::Function, llmFo
end
responsedict = GeneralUtils.textToDict(response, header;
dictKey=dictkey, symbolkey=true)
dictKey=dictkey, symbolkey=false)
responsedict[:score] = responsedict[:score][1] # some time "6\nThe trajectories are incomplete" is generated but I only need the number.
responsedict["score"] = responsedict["score"][1] # some time "6\nThe trajectories are incomplete" is generated but I only need the number.
try
responsedict[:score] = parse(Int, responsedict[:score]) # convert string "5" into integer 5
responsedict["score"] = parse(Int, responsedict["score"]) # convert string "5" into integer 5
catch
errornote = "Your previous attempt's score has wrong format"
println("\nERROR SQLLLM evaluator() Attempt $attempt/$maxattempt. $errornote ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
continue
end
accepted_as_answer::AbstractString = responsedict[:accepted_as_answer]
accepted_as_answer::AbstractString = responsedict["accepted_as_answer"]
if accepted_as_answer ["yes", "no"]
errornote = "Your previous attempt's accepted_as_answer has wrong format"
println("\nERROR SQLLLM evaluator() Attempt $attempt/$maxattempt. $errornote --(not qualify response)--> $(responsedict[:accepted_as_answer]) ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
println("\nERROR SQLLLM evaluator() Attempt $attempt/$maxattempt. $errornote --(not qualify response)--> $(responsedict["accepted_as_answer"]) ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
continue
end
# add to state here instead to in transition() because the latter causes julia extension crash (a bug in julia extension)
state[:evaluation] = "$(responsedict[:trajectory_evaluation]) $(responsedict[:answer_evaluation])"
state[:evaluationscore] = responsedict[:score]
state[:accepted_as_answer] = responsedict[:accepted_as_answer]
state[:suggestion] = responsedict[:suggestion]
state["evaluation"] = "$(responsedict["trajectory_evaluation"]) $(responsedict["answer_evaluation"])"
state["evaluationscore"] = responsedict["score"]
state["accepted_as_answer"] = responsedict["accepted_as_answer"]
state["suggestion"] = responsedict["suggestion"]
# mark as terminal state when the answer is achieved
if accepted_as_answer ["Yes", "yes"]
# mark the state as terminal state because the evaluation say so.
state[:isterminal] = true
state["isterminal"] = true
# evaluation score as reward because different answers hold different value for the user.
state[:reward] = responsedict[:score]
state["reward"] = responsedict["score"]
end
println("\nSQLLLM evaluator() ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
@@ -776,7 +776,7 @@ function evaluator(state::T1, thoughtDict, text2textInstructLLM::Function, llmFo
# end
# end
return responsedict[:score]
return responsedict["score"]
end
error("Evaluator failed to generate an evaluation, Response: \n$response\n<|End of error|>")
end
@@ -952,14 +952,14 @@ end
```jldoctest
julia> using SQLLLM, DataStructures
julia> state = Dict(
:isterminal => false,
:lesson => nothing,
:reward => 0,
:evaluation => "None",
:accepted_as_answer => "No",
:thoughtHistory => OrderedDict{Symbol, Any}(:question => "How many wines do you have that can be paired with lamb?"),
:evaluationscore => 0,
:suggestion => "None"
"isterminal" => false,
"lesson" => nothing,
"reward" => 0,
"evaluation" => "None",
"accepted_as_answer" => "No",
"thoughtHistory" => OrderedDict{String, Any}("question" => "How many wines do you have that can be paired with lamb?"),
"evaluationscore" => 0,
"suggestion" => "None"
)
```
@@ -987,18 +987,18 @@ function transition(state::T, args::NamedTuple
# map action and input() to llm function
response =
if thoughtDict[:action_name] == "listalltables"
# deepcopy(state[:virtualCustomerChatHistory]) because I want to keep it clean
if thoughtDict["action_name"] == "listalltables"
# deepcopy(state["virtualCustomerChatHistory"]) because I want to keep it clean
# so that other simulation start from this same node is not contaminated with actioninput
listAllTable_json(executeSQL)
elseif thoughtDict[:action_name] == "TABLEINFO"
input = thoughtDict[:action_input]
elseif thoughtDict["action_name"] == "TABLEINFO"
input = thoughtDict["action_input"]
tableinfo(executeSQL, input)
elseif thoughtDict[:action_name] == "RUNSQL"
response = SQLexecution(executeSQL, thoughtDict[:action_input])
if response[:success]
extracted = extractContent_dataframe(response[:result], text2textInstructLLM,
thoughtDict[:action_input], llmFormatName)
response = SQLexecution(executeSQL, thoughtDict["action_input"])
if response["success"]
extracted = extractContent_dataframe(response["result"], text2textInstructLLM,
thoughtDict["action_input"], llmFormatName)
(rawresponse=response[:result], result=extracted, errormsg=nothing, success=true)
else
(result=nothing, errormsg=response[:errormsg], success=false)
@@ -1007,12 +1007,12 @@ function transition(state::T, args::NamedTuple
error("undefined LLM function. Requesting $(thoughtDict[:action_name])")
end
# this section allow LLM functions above to have different return values.
success::Bool = haskey(response, :success) ? response[:success] : false
result = success ? response[:result] : response[:errormsg]
rawresponse = haskey(response, :rawresponse) ? response[:rawresponse] : nothing
select = haskey(response, :select) ? response[:select] : nothing
reward::Integer = haskey(response, :reward) ? response[:reward] : 0
isterminal::Bool = haskey(response, :isterminal) ? response[:isterminal] : false
success::Bool = haskey(response, "success") ? response["success"] : false
result = success ? response["result"] : response["errormsg"]
rawresponse = haskey(response, "rawresponse") ? response["rawresponse"] : nothing
select = haskey(response, "select") ? response["select"] : nothing
reward::Integer = haskey(response, "reward") ? response["reward"] : 0
isterminal::Bool = haskey(response, "isterminal") ? response["isterminal"] : false
newNodeKey, newstate = makeNewState(state, thoughtDict, rawresponse, JSON3.write(result), select, reward, isterminal)
progressvalue::Integer = evaluatorF(newstate, thoughtDict, text2textInstructLLM, llmFormatName)
@@ -1124,19 +1124,19 @@ function query(query::T, executeSQL::Function, text2textInstructLLM::Function;
# do MCTS if no data in the database
# add extra context for Evaluator so that it knows the observation is from seaching a database
initialstate = Dict{Symbol, Any}(
:reward=> 0,
:isterminal=> false,
:evaluation=> "None",
:evaluationscore=> 0,
:suggestion=> "None",
:accepted_as_answer=> "No",
:lesson=> nothing,
initialstate = Dict{String, Any}(
"reward"=> 0,
"isterminal"=> false,
"evaluation"=> "None",
"evaluationscore"=> 0,
"suggestion"=> "None",
"accepted_as_answer"=> "No",
"lesson"=> nothing,
# contain question, thought_1, action_1, observation_1, thought_2, ...
:thoughtHistory=> OrderedDict{Symbol, Any}(
"thoughtHistory"=> OrderedDict{String, Any}(
#[] :recap=>,
:question=> query,
"question"=> query,
),
)
# context = Dict(
@@ -1272,7 +1272,7 @@ function query(query::T, executeSQL::Function, text2textInstructLLM::Function;
llmFormatName=llmFormatName
)
earlystop(state) = state[:reward] >= 8 ? true : false
earlystop(state) = state["reward"] >= 8 ? true : false
root, _, resultState, highValueState =
LLMMCTS.runMCTS(initialstate, transition, transitionargs;
@@ -1294,22 +1294,22 @@ function query(query::T, executeSQL::Function, text2textInstructLLM::Function;
resultState = highValueState[selected]
end
latestKey, latestInd = GeneralUtils.findHighestIndexKey(resultState[:thoughtHistory], "observation")
action_input = Symbol("action_input_$latestInd") # latest sql
sql = resultState[:thoughtHistory][action_input]
extractedTableContent = resultState[:thoughtHistory][latestKey]
action_input = "action_input_$latestInd" # latest sql
sql = resultState["thoughtHistory"][action_input]
extractedTableContent = resultState["thoughtHistory"][latestKey]
# add to vectorDB only if the answer is achieved and the state is terminal
if insertSQLVectorDB !== nothing && resultState[:isterminal] == true &&
resultState[:rawresponse] !== nothing
if insertSQLVectorDB !== nothing && resultState["isterminal"] == true &&
resultState["rawresponse"] !== nothing
insertSQLVectorDB(resultState[:thoughtHistory][:question], sql)
insertSQLVectorDB(resultState["thoughtHistory"]["question"], sql)
end
if extractedTableContent === nothing
println("\nSQLLLM query() return nothing ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
end
result = (text=extractedTableContent, rawresponse=resultState[:rawresponse])
result = (text=extractedTableContent, rawresponse=resultState["rawresponse"])
return result
end
@@ -1330,32 +1330,32 @@ julia>
"""
function makeNewState(currentstate::T1, thoughtDict::T4, rawresponse, response::T2, select::Union{T3, Nothing},
reward::T3, isterminal::Bool
)::NamedTuple{(:newNodeKey, :newstate), Tuple{String, Dict{Symbol, <:Any}}} where {T1<:AbstractDict, T2<:AbstractString, T3<:Number, T4<:AbstractDict}
)::NamedTuple{(:newNodeKey, :newstate), Tuple{String, Dict{String, <:Any}}} where {T1<:AbstractDict, T2<:AbstractString, T3<:Number, T4<:AbstractDict}
keys = [:plan, :action_name, :action_input, :observation]
# latestKeys = []
currentstate_latestKey, currentstate_latestIndice =
GeneralUtils.findHighestIndexKey(currentstate[:thoughtHistory], keys[1])
GeneralUtils.findHighestIndexKey(currentstate["thoughtHistory"], keys[1])
nextindice = currentstate_latestKey !== nothing ? currentstate_latestIndice + 1 : 1
# currentstate_latestKey == :NA ? 1 : currentstate_latestIndice + 1
# currentstate_latestKey == "NA" ? 1 : currentstate_latestIndice + 1
currentstate_latestKey = makekey.(keys, nextindice)
# add Thought, action, observation to thoughtHistory
newstate = deepcopy(currentstate)
for (x, y) in zip(keys, currentstate_latestKey)
if x != :observation
newstate[:thoughtHistory][y] = thoughtDict[Symbol(x)]
if x != "observation"
newstate["thoughtHistory"][y] = thoughtDict[x]
else
newstate[:thoughtHistory][y] = response
newstate["thoughtHistory"][y] = response
end
end
newstate[:reward] = reward
newstate[:select] = select
newstate[:isterminal] = isterminal
newstate[:rawresponse] = rawresponse # whatever return from action
newstate["reward"] = reward
newstate["select"] = select
newstate["isterminal"] = isterminal
newstate["rawresponse"] = rawresponse # whatever return from action
newNodeKey = GeneralUtils.uuid4snakecase()
@@ -1429,8 +1429,8 @@ function generatequestion(state::T1, context, text2textInstructLLM::Function,
dictkey = ["q1"]
workprogress = ""
for (k, v) in state[:thoughtHistory]
if k [:query]
for (k, v) in state["thoughtHistory"]
if k ["query"]
workprogress *= "$k: $v\n"
end
end
@@ -1441,8 +1441,8 @@ function generatequestion(state::T1, context, text2textInstructLLM::Function,
for attempt in 1:maxattempt
usermsg =
"""
$(context[:tablelist])
User query: $(state[:thoughtHistory][:question])
$(context["tablelist"])
User query: $(state["thoughtHistory"]["question"])
Example: $similarSQL
Your work progress: $workprogress
P.S. $errornote
@@ -1474,8 +1474,8 @@ function generatequestion(state::T1, context, text2textInstructLLM::Function,
end
responsedict = GeneralUtils.textToDict(response, header;
dictKey=dictkey, symbolkey=true)
response = "Q1: " * responsedict[:q1]
dictKey=dictkey, symbolkey=false)
response = "Q1: " * responsedict["q1"]
println("\nSQLLLM generatequestion() ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
pprintln(Dict(responsedict))
return response
+49 -49
View File
@@ -287,17 +287,17 @@ function getdata_transition(state::T, args::NamedTuple
# decisionMaker::Function = args[:decisionMaker]
# evaluator::Function = args[:evaluator]
# reflector::Function = args[:reflector]
context = args[:context]
executeSQL::Function = args[:executeSQL]
text2textInstructLLM::Function = args[:text2textInstructLLM]
context = args["context"]
executeSQL::Function = args["executeSQL"]
text2textInstructLLM::Function = args["text2textInstructLLM"]
thought, sql =
if state[:code] !== nothing
result = getdata_decisionMaker(state, context, text2textInstructLLM)
result[:thought], result[:code]
else
nothing, state[:question]
end
thought, sql =
if state["code"] !== nothing
result = getdata_decisionMaker(state, context, text2textInstructLLM)
result["thought"], result["code"]
else
nothing, state["question"]
end
# make new state
newNodeKey = GeneralUtils.uuid4snakecase()
@@ -314,15 +314,15 @@ function getdata_transition(state::T, args::NamedTuple
isterminal=false)
end
println("getdata_transition() 1 ", @__FILE__, " ", @__LINE__)
newstate[:code] = sql
newstate[:response] = response
newstate[:errorexplain] = thought
newstate[:errormsg] = errormsg
newstate[:reward] = reward
newstate[:isterminal] = isterminal
newstate["code"] = sql
newstate["response"] = response
newstate["errorexplain"] = thought
newstate["errormsg"] = errormsg
newstate["reward"] = reward
newstate["isterminal"] = isterminal
if response !== nothing
extracted = extractContent_dataframe(response, context, text2textInstructLLM)
newstate[:response] = extracted
newstate["response"] = extracted
end
println("getdata_transition() 2 ", @__FILE__, " ", @__LINE__)
stateevaluation = "None"
@@ -389,10 +389,10 @@ function getdata_decisionMaker(state::Dict, context::Dict, text2textInstructLLM:
for attempt in 1:10
usermsg = """
Context:
$(context[:mentionedTableInfo])
User intention: $(context[:userintention])
Code executed from the last round: $(state[:code])
Execution error: $(state[:errormsg])
$(context["mentionedTableInfo"])
User intention: $(context["userintention"])
Code executed from the last round: $(state["code"])
Execution error: $(state["errormsg"])
$noise
$note_flag
"""
@@ -414,13 +414,13 @@ function getdata_decisionMaker(state::Dict, context::Dict, text2textInstructLLM:
dictkey = ["plan", "code"]
responsedict = GeneralUtils.textToDict(response, header;
dictKey=dictkey, symbolkey=true)
_code = responsedict[:code]
dictKey=dictkey, symbolkey=false)
_code = responsedict["code"]
code = strip(_code)
if length(code) < 2
error("No code available.")
elseif code == state[:code]
elseif code == state["code"]
error("generated code is the same as earlier.")
else
end
@@ -440,7 +440,7 @@ function getdata_decisionMaker(state::Dict, context::Dict, text2textInstructLLM:
println("\n~~~ getdata_decisionMaker() ", @__FILE__, " ", @__LINE__)
pprintln(Dict(responsedict))
return (thought=responsedict[:comprehension], code=code, success=true, errormsg=nothing)
return (thought=responsedict["comprehension"], code=code, success=true, errormsg=nothing)
catch e
io = IOBuffer()
showerror(io, e)
@@ -651,12 +651,12 @@ function extractContent_dataframe(df::DataFrame, text2textInstructLLM::Function,
end
responsedict = GeneralUtils.textToDict(response, header;
dictKey=dictkey, symbolkey=true)
dictKey=dictkey, symbolkey=false)
# result = dfstr
result =
"""
Summary: $(responsedict[:search_summary])
Summary: $(responsedict["search_summary"])
More details: $dfstr
"""
@@ -778,8 +778,8 @@ function getTableNameFromSQL(sql::T, text2textInstructLLM::Function,
response = text2textInstructLLM(prompt, modelsize="medium")
response = GeneralUtils.deFormatLLMtext(response, llmFormatName)
responsedict = GeneralUtils.textToDict(response, header;
dictKey=dictkey, symbolkey=true)
response = copy(JSON3.read(responsedict[:table_name]))
dictKey=dictkey, symbolkey=false)
response = copy(JSON3.read(responsedict["table_name"]))
return response
catch e
@@ -862,21 +862,21 @@ function compareState(question::String, highValueStateList::Vector{T},
Let's begin!
"""
potentialSolution = []
keys = [:action_input, :observation]
# extract the last action_name, action_input, observation of each state in highValueStateList and store them in a dictionary then push into potentialSolution
for state in highValueStateList
thoughtHistory = state[:thoughtHistory]
_, currentstate_latestIndice =
GeneralUtils.findHighestIndexKey(thoughtHistory, keys[1])
latestKeys = makekey.(keys, currentstate_latestIndice)
d = Dict()
# get the last action_name, action_input, observation of currentstate
for (i,v) in enumerate(keys)
d[v] = thoughtHistory[latestKeys[i]]
end
push!(potentialSolution, d)
end
potentialSolution = []
keys = ["action_input", "observation"]
# extract the last action_name, action_input, observation of each state in highValueStateList and store them in a dictionary then push into potentialSolution
for state in highValueStateList
thoughtHistory = state["thoughtHistory"]
_, currentstate_latestIndice =
GeneralUtils.findHighestIndexKey(thoughtHistory, keys[1])
latestKeys = makekey.(keys, currentstate_latestIndice)
d = Dict()
# get the last action_name, action_input, observation of currentstate
for (i,v) in enumerate(keys)
d[v] = thoughtHistory[latestKeys[i]]
end
push!(potentialSolution, d)
end
"""
# put potential solutions from potentialSolution into the following form
@@ -944,11 +944,11 @@ function compareState(question::String, highValueStateList::Vector{T},
continue
end
responsedict = GeneralUtils.textToDict(response, header; dictKey=dictkey, symbolkey=true)
responsedict = GeneralUtils.textToDict(response, header; dictKey=dictkey, symbolkey=false)
responsedict[:selected_response_number] = responsedict[:selected_response_number][1] # some time "6\nThe trajectories are incomplete" is generated but I only need the number.
try
responsedict[:selected_response_number] = parse(Int, responsedict[:selected_response_number]) # convert string "5" into integer 5
responsedict["selected_response_number"] = responsedict["selected_response_number"][1] # some time "6\nThe trajectories are incomplete" is generated but I only need the number.
try
responsedict["selected_response_number"] = parse(Int, responsedict["selected_response_number"]) # convert string "5" into integer 5
catch
errornote = "In your previous attempt, Selected_response_number was not a number. It must be a number."
println("\nERROR SQLLLM compareState() Attempt $attempt. $errornote ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
@@ -958,7 +958,7 @@ function compareState(question::String, highValueStateList::Vector{T},
println("\n~~~ compareState() ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
pprintln(Dict(responsedict))
return responsedict[:selected_response_number]
return responsedict["selected_response_number"]
end
error("compareState() failed to generate an evaluation, Response: \n$response\n<|End of error|>", @__FILE__, ":", @__LINE__, " $(Dates.now())")
end
+1 -1
View File
@@ -2,7 +2,7 @@ module util
export makekey
makekey(key, indice) = Symbol("$(key)_$indice")
makekey(key, indice) = "$(key)_$indice"
+1 -1
View File
@@ -353,7 +353,7 @@ SELECT * FROM wine WHERE wine_type = 'red' AND country = 'France' AND sweetness
# "The user's question is to search the database for wines that have a type of \"white\", are from \"France\", and have a sweetness level of 1. The thought is correct in identifying the conditions needed to filter the wine table. The action taken is to execute a SQL query to retrieve the desired data, which is also correct. The observation provides a search summary and two search results that match the user's question. Each result includes details about the wine such as ID, name, brand, manufacturer, region, country, type, grape variety, serving temperature, intensity, sweetness, tannin, and acidity.",
# :accepted_as_answer => "Yes",
# :thoughtHistory =>
# OrderedDict{Symbol, Any}(:question => "Search the database for wine_type: white, country: France, sweetness: 1", :thought_1 => "The user wants to search the database for wines that have a type of \"white\", are from \"France\", and have a sweetness level of 1. To achieve this, we need to filter the wine table based on these conditions.", :action_name_1 => "GETDATA", :action_input_1 => "SELECT * FROM wine WHERE wine.wine_type = 'white' AND wine.country = 'France' AND wine.sweetness = 1;", :observation_1 => "\"Search summary: The resulting table represents wines.\\nSearch result: 1) wine_id: 5b6b6df9-d87c-4f33-8995-7249c2ecc917, wine_name: corton-charlemagne grand cru, brand: domaine des croix, manufacturer: domaine des croix, region: bourgogne, country: France, wine_type: white, grape_variety: cote de beaune blanc, serving_temperature: 11 to 13 Celsius, intensity: 4, sweetness: 1, tannin: missing, acidity: 3, fizziness: missing\\n2) wine_id: 1ad27d16-ef64-4907-acf1-40631630c143, wine_name: puligny-montrachet 1er cru 'les demoiselles', brand: amiot guy, manufacturer: amiot guy, region: bourgogne, country: France, wine_type: white, grape_variety: cote de beaune blanc, serving_temperature: 11 to 13 Celsius, intensity: 4, sweetness: 1, tannin: missing, acidity: 3, fizziness: missing\\n\\n\""),
# OrderedDict{String, Any}("question" => "Search the database for wine_type: white, country: France, sweetness: 1", "thought_1" => "The user wants to search the database for wines that have a type of \"white\", are from \"France\", and have a sweetness level of 1. To achieve this, we need to filter the wine table based on these conditions.", "action_name_1" => "GETDATA", "action_input_1" => "SELECT * FROM wine WHERE wine.wine_type = 'white' AND wine.country = 'France' AND wine.sweetness = 1;", "observation_1" => "\"Search summary: The resulting table represents wines.\\nSearch result: 1) wine_id: 5b6b6df9-d87c-4f33-8995-7249c2ecc917, wine_name: corton-charlemagne grand cru, brand: domaine des croix, manufacturer: domaine des croix, region: bourgogne, country: France, wine_type: white, grape_variety: cote de beaune blanc, serving_temperature: 11 to 13 Celsius, intensity: 4, sweetness: 1, tannin: missing, acidity: 3, fizziness: missing\\n2) wine_id: 1ad27d16-ef64-4907-acf1-40631630c143, wine_name: puligny-montrachet 1er cru 'les demoiselles', brand: amiot guy, manufacturer: amiot guy, region: bourgogne, country: France, wine_type: white, grape_variety: cote de beaune blanc, serving_temperature: 11 to 13 Celsius, intensity: 4, sweetness: 1, tannin: missing, acidity: 3, fizziness: missing\\n\\n\""),
# :evaluationscore => 9,
# :select => nothing,
# :suggestion => "None")