update
This commit is contained in:
+101
-44
@@ -75,7 +75,7 @@ OrderedDict{String, Any} with 4 entries:
|
||||
"""
|
||||
function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
|
||||
) where {T<:agent}
|
||||
|
||||
@info "YiemAgent decisionMaker() 1 " @__LINE__
|
||||
# lessonDict = copy(JSON.parsefile("lesson.json"))
|
||||
|
||||
# lesson =
|
||||
@@ -110,7 +110,7 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
|
||||
<internal_context_for_assistant>
|
||||
</internal_context_for_assistant>
|
||||
"""
|
||||
|
||||
@info "YiemAgent decisionMaker() 2 " @__LINE__
|
||||
# add context to text of the latest message (in the front).
|
||||
# use for loop because in openai format, each msg may contain both text and image.
|
||||
for d in a.chathistory[end]["content"]
|
||||
@@ -123,28 +123,27 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
|
||||
response = nothing # placeholder for show when error msg show up
|
||||
|
||||
for attempt in 1:maxattempt
|
||||
if attempt > 1
|
||||
println("\nYiemAgent decisionMaker() attempt $attempt/$maxattempt ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
end
|
||||
@info "YiemAgent decisionMaker() 3 " @__LINE__
|
||||
|
||||
msg = Dict(
|
||||
"model" => "gemma-4-E4B-it-UD-Q4_K_XL",
|
||||
"messages" => a.chathistory,
|
||||
"temperature" => 0.7
|
||||
)
|
||||
|
||||
@info "YiemAgent decisionMaker() 4 " @__LINE__
|
||||
response = a.context.text2textInstructLLM(a.id, msg)
|
||||
@info "YiemAgent decisionMaker() 5 " @__LINE__
|
||||
response = GeneralUtils.clean_json_response(response)
|
||||
response = GeneralUtils.remove_french_accents(response)
|
||||
think, response = GeneralUtils.extractthink(response)
|
||||
response = String(split(response, ", observation")[1]) # in case LLM generate observation key which it isn't supposed to
|
||||
response = strip(response)
|
||||
|
||||
@info "YiemAgent decisionMaker() 6 " @__LINE__
|
||||
# dollar sign in Julia means string interpolation
|
||||
while occursin('$', response)
|
||||
response = replace(response, '$' => "USD")
|
||||
end
|
||||
|
||||
@info "YiemAgent decisionMaker() 7 " @__LINE__
|
||||
responsedict = nothing
|
||||
if occursin(requiredKeys[2], response)
|
||||
try
|
||||
@@ -155,14 +154,24 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
|
||||
continue
|
||||
end
|
||||
end
|
||||
|
||||
@info "YiemAgent decisionMaker() 8 " @__LINE__
|
||||
# check whether all answer's key points are in responsedict
|
||||
println("\n---")
|
||||
println(responsedict)
|
||||
println("---\n")
|
||||
ispass, errormsg = GeneralUtils.checkAgentResponse_JSON(responsedict, requiredKeys)
|
||||
@info "YiemAgent decisionMaker() 9 " @__LINE__
|
||||
if !ispass
|
||||
errornote = errormsg
|
||||
println("\nERROR YiemAgent decisionMaker() $errornote --(not qualify response)-> $responsedict", @__FILE__, ":", @__LINE__, " $(Dates.now())\n")
|
||||
continue
|
||||
end
|
||||
@info "YiemAgent decisionMaker() 10 " @__LINE__
|
||||
if responsedict["action_input"] == "CHAT_BOX" &&
|
||||
occursin("similar", responsedict["action_input"])
|
||||
@info "illegal CHAT_BOX search term" @__LINE__
|
||||
continue
|
||||
end
|
||||
|
||||
# if responsedict["action_name"] ∉ ["CHAT_BOX", "SEARCH_WINE_DATABASE", "PRESENT_WINE_GUIDELINE", "END_CONVER_GUIDELINE"]
|
||||
# errornote = "Your previous attempt didn't use the given functions"
|
||||
@@ -172,7 +181,7 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
|
||||
|
||||
# println("\nYiem decisionMaker() ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
# pprintln(responsedict)
|
||||
|
||||
@info "YiemAgent decisionMaker() 11 " @__LINE__
|
||||
return responsedict
|
||||
end
|
||||
error("DecisionMaker failed to generate a thought ", response)
|
||||
@@ -380,49 +389,85 @@ function conversation(a::sommelier; userinput::Union{Dict{String, Any}, JSON.Obj
|
||||
|
||||
@info "YiemAgent conversation() 2-3 think count $loopcount " @__LINE__
|
||||
thoughtdict, result_raw = think(a)
|
||||
@info "YiemAgent conversation() 2-4 think count $loopcount " @__LINE__
|
||||
if thoughtdict["action_name"] ∈ ["CHAT_BOX"]
|
||||
@info "YiemAgent conversation() 2-4 think count $loopcount " @__LINE__
|
||||
@info "YiemAgent conversation() 2-5 think count $loopcount " @__LINE__
|
||||
|
||||
assistant_response = Dict{String, Any}(
|
||||
"role" => "assistant",
|
||||
"content" => [Dict("type" => "text", "text" => thoughtdict["action_input"]),]
|
||||
)
|
||||
addNewMessage(a, "assistant", assistant_response; maximumMsg=maximumMsg)
|
||||
@info "YiemAgent conversation() 2-5 think count $loopcount " @__LINE__
|
||||
return thoughtdict["action_input"]
|
||||
# elseif thoughtdict["action_name"] ∈ ["CHAT_BOX"]
|
||||
# @info "YiemAgent conversation() 2-4 think count $loopcount " @__LINE__
|
||||
# assistant_response = Dict{String, Any}(
|
||||
# "role" => "assistant",
|
||||
# "content" => [
|
||||
# Dict("type" => "text", "text" => thoughtdict["action_input"]),
|
||||
# Dict( #WORKING put 1st image here
|
||||
# "type" => "image_url",
|
||||
# "image_url" => Dict("url" => image1_data_uri)
|
||||
# ),
|
||||
# Dict( #WORKING put 2nd image here
|
||||
# "type" => "image_url",
|
||||
# "image_url" => Dict("url" => image2_data_uri)
|
||||
# ),
|
||||
# ]
|
||||
# )
|
||||
# addNewMessage(a, "assistant", assistant_response; maximumMsg=maximumMsg)
|
||||
|
||||
# return thoughtdict["action_input"] #XXX change output from string to dict
|
||||
else
|
||||
items_info = []
|
||||
if haskey(a.memory["shortmem"], "items_info")
|
||||
for (i, item) in enumerate(a.memory["shortmem"]["items_info"])
|
||||
if haskey(item, "wine_name") && occursin(item["wine_name"], thoughtdict["action_input"])
|
||||
push!(items_info, item)
|
||||
deleteat!(a.memory["shortmem"]["items_info"], i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
response_to_frontend = Dict{String, Any}(
|
||||
"role" => "assistant",
|
||||
"content" => [
|
||||
Dict("type" => "text", "text" => thoughtdict["action_input"]),
|
||||
Dict(
|
||||
"type" => "items_info",
|
||||
"items_info" => items_info
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
""" intended message to send to frontend should have the following format.
|
||||
response_to_frontend = Dict{String, Any}(
|
||||
"role" => "assistant",
|
||||
"content" => [
|
||||
Dict("type" => "text", "text" => "assistant_text_response"),
|
||||
Dict(
|
||||
"type" => "items_info",
|
||||
"items_info" => [
|
||||
Dict(
|
||||
"wine_name"=> "wine name 1",
|
||||
"wine_id"=> "...",
|
||||
"image"=> base64 encoded image,
|
||||
...
|
||||
),
|
||||
Dict(
|
||||
"wine_name"=> "wine name 2",
|
||||
"wine_id"=> "...",
|
||||
"image"=> base64 encoded image,
|
||||
...
|
||||
),
|
||||
]
|
||||
),
|
||||
]
|
||||
)
|
||||
"""
|
||||
|
||||
@info "YiemAgent conversation() 2-6 think count $loopcount " @__LINE__
|
||||
return response_to_frontend
|
||||
else # still in action
|
||||
@info "YiemAgent conversation() 2-7 think count $loopcount " @__LINE__
|
||||
action_name = thoughtdict["action_name"]
|
||||
action_input = thoughtdict["action_input"]
|
||||
@info "YiemAgent conversation() 2-8 think count $loopcount " @__LINE__
|
||||
action_call = Dict{String, Any}(
|
||||
"role" => "action_call",
|
||||
"content" => [Dict("type" => "text", "text" => "{action_name: $action_name, action_input: $action_input}"),]
|
||||
)
|
||||
@info "YiemAgent conversation() 2-9 think count $loopcount " @__LINE__
|
||||
addNewMessage(a, "action_call", action_call; maximumMsg=maximumMsg)
|
||||
|
||||
@info "YiemAgent conversation() 2-10 think count $loopcount " @__LINE__
|
||||
action_result = thoughtdict["action_result"]
|
||||
actionresult = Dict{String, Any}(
|
||||
"role" => "action_result",
|
||||
"content" => [Dict("type" => "text", "text" => "$action_result"),]
|
||||
)
|
||||
@info "YiemAgent conversation() 2-11 think count $loopcount " @__LINE__
|
||||
addNewMessage(a, "actionresult", actionresult; maximumMsg=maximumMsg)
|
||||
@info "YiemAgent conversation() 2-12 think count $loopcount " @__LINE__
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -442,15 +487,16 @@ julia>
|
||||
"""
|
||||
function think(a::T)::NamedTuple{(:thoughtdict, :result_raw), Tuple{OrderedDict, Any}} where {T<:agent}
|
||||
# a.memory[:recap] = generateSituationReport(a, a.context["text"2textInstructLLM]; skiprecent=0)
|
||||
@info "YiemAgent think() 1-1 " @__LINE__
|
||||
thoughtdict = decisionMaker(a)
|
||||
@info "YiemAgent think() 1 " @__LINE__
|
||||
@info "YiemAgent think() 1-2 " @__LINE__
|
||||
# pprintln(thoughtdict)
|
||||
|
||||
result_raw = nothing
|
||||
if thoughtdict["action_name"] ∈ ["CHAT_BOX"]
|
||||
@info "YiemAgent think() 2 " @__LINE__
|
||||
@info "YiemAgent think() 2-1 " @__LINE__
|
||||
thoughtdict, result_raw = generatechat!(a)
|
||||
|
||||
@info "YiemAgent think() 2-2 " @__LINE__
|
||||
elseif thoughtdict["action_name"] == "END_CONVER_GUIDELINE"
|
||||
@info "YiemAgent think() 3 " @__LINE__
|
||||
thoughtdict, result_raw = end_conversation_guideline!(a, thoughtdict)
|
||||
@@ -462,7 +508,14 @@ function think(a::T)::NamedTuple{(:thoughtdict, :result_raw), Tuple{OrderedDict,
|
||||
elseif thoughtdict["action_name"] == "SEARCH_WINE_DATABASE"
|
||||
@info "YiemAgent think() 5 " @__LINE__
|
||||
thoughtdict, result_raw = search_wine_database!(a, thoughtdict; useSQLLLM=false)
|
||||
#WORKING result_raw will be a df. i need to get images so i can send to frontend
|
||||
if result_raw !== nothing && result_raw isa Vector
|
||||
if haskey(a.memory["shortmem"], "items_info")
|
||||
append!(a.memory["shortmem"]["items_info"], result_raw)
|
||||
else
|
||||
a.memory["shortmem"]["items_info"] = result_raw
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
@info "YiemAgent think() 6 " @__LINE__
|
||||
error("condition is not defined ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
@@ -629,7 +682,7 @@ function generatechat!(a::T; maxattempt::Integer=10
|
||||
"action_name": "...",
|
||||
"action_input": "..."
|
||||
"""
|
||||
|
||||
@info "YiemAgent generatechat!() 1 " @__LINE__
|
||||
system_msg = Dict(
|
||||
"role" => "system",
|
||||
"content" => [
|
||||
@@ -644,7 +697,7 @@ function generatechat!(a::T; maxattempt::Integer=10
|
||||
|
||||
errornote = "N/A"
|
||||
response = nothing # placeholder for show when error msg show up
|
||||
|
||||
@info "YiemAgent generatechat!() 2 " @__LINE__
|
||||
for attempt in 1:maxattempt
|
||||
if attempt > 1
|
||||
println("\nYiemAgent generatechat() attempt $attempt/$maxattempt ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
@@ -660,10 +713,9 @@ function generatechat!(a::T; maxattempt::Integer=10
|
||||
response = GeneralUtils.clean_json_response(response)
|
||||
response = GeneralUtils.remove_french_accents(response)
|
||||
think, response = GeneralUtils.extractthink(response)
|
||||
response = String(split(response, ", observation")[1]) # in case LLM generate observation key which it isn't supposed to
|
||||
|
||||
response = strip(response)
|
||||
|
||||
response = strip(response)
|
||||
@info "YiemAgent generatechat!() 3 " @__LINE__
|
||||
responsedict = nothing
|
||||
if occursin(requiredKeys[2], response)
|
||||
try
|
||||
@@ -673,8 +725,12 @@ function generatechat!(a::T; maxattempt::Integer=10
|
||||
println("\nERROR YiemAgent generatechat() failed to parse response: $response ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
continue
|
||||
end
|
||||
else
|
||||
println("\nERROR YiemAgent generatechat() $errornote --(not qualify response)> $responsedict", @__FILE__, ":", @__LINE__, " $(Dates.now())\n")
|
||||
continue
|
||||
end
|
||||
|
||||
@info "YiemAgent generatechat!() 4 " @__LINE__
|
||||
# check whether all answer's key points are in responsedict
|
||||
ispass, errormsg = GeneralUtils.checkAgentResponse_JSON(responsedict, requiredKeys)
|
||||
if !ispass
|
||||
@@ -682,7 +738,7 @@ function generatechat!(a::T; maxattempt::Integer=10
|
||||
println("\nERROR YiemAgent generatechat() $errornote --(not qualify response)> $responsedict", @__FILE__, ":", @__LINE__, " $(Dates.now())\n")
|
||||
continue
|
||||
end
|
||||
|
||||
@info "YiemAgent generatechat!() 5 " @__LINE__
|
||||
# if responsedict["action_name"] ∉ ["CHAT_BOX", "SEARCH_WINE_DATABASE", "PRESENT_WINE_GUIDELINE", "END_CONVER_GUIDELINE"]
|
||||
# errornote = "Your previous attempt didn't use the given functions"
|
||||
# println("\nERROR YiemAgent decisionMaker() $errornote --(not qualify response)--> $(responsedict["action_name"])", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
@@ -691,7 +747,8 @@ function generatechat!(a::T; maxattempt::Integer=10
|
||||
|
||||
# println("\nYiem decisionMaker() ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
# pprintln(responsedict)
|
||||
|
||||
responsedict["action_result"] = "Action result is the next user dialogue."
|
||||
@info "YiemAgent generatechat!() 6 " @__LINE__
|
||||
return (thoughtdict=responsedict, result_raw=responsedict["action_input"])
|
||||
end
|
||||
error("YiemAgent generatechat() failed to generate a thought ", response)
|
||||
|
||||
Reference in New Issue
Block a user