use string key for dict
This commit is contained in:
+104
-104
@@ -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
@@ -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
@@ -2,7 +2,7 @@ module util
|
||||
|
||||
export makekey
|
||||
|
||||
makekey(key, indice) = Symbol("$(key)_$indice")
|
||||
makekey(key, indice) = "$(key)_$indice"
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user