update
This commit is contained in:
+244
-304
@@ -1,6 +1,6 @@
|
||||
module interface
|
||||
|
||||
export addNewMessage, conversation, decisionMaker, evaluator, reflector, generatechat,
|
||||
export addNewMessage, conversation, decisionMaker, reflector, generatechat,
|
||||
generalconversation, detectWineryName, generateSituationReport
|
||||
|
||||
using JSON3, DataStructures, Dates, UUIDs, HTTP, Random, PrettyPrinting, Serialization,
|
||||
@@ -55,6 +55,8 @@ end
|
||||
config
|
||||
- `state::T2`
|
||||
a game state
|
||||
|
||||
# Keyword Arguments
|
||||
|
||||
# Return
|
||||
- `thoughtDict::Dict`
|
||||
@@ -90,8 +92,6 @@ julia> output_thoughtDict = Dict(
|
||||
|
||||
# TODO
|
||||
- [] update docstring
|
||||
- [x] implement the function
|
||||
- [] implement RAG to pull similar experience
|
||||
- [] use customerinfo
|
||||
- [] user storeinfo
|
||||
|
||||
@@ -294,15 +294,13 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol,Any} where {T<:agen
|
||||
Dict(:name => "user", :text => usermsg)
|
||||
]
|
||||
|
||||
#[WORKING] change qwen format put in model format
|
||||
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct")
|
||||
prompt *= """
|
||||
<|start_header_id|>assistant<|end_header_id|>
|
||||
"""
|
||||
# change qwen format put in model format
|
||||
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="qwen")
|
||||
|
||||
response = a.func[:text2textInstructLLM](prompt)
|
||||
response = GeneralUtils.remove_french_accents(response)
|
||||
response = replace(response, '*'=>"")
|
||||
response = replace(response, "**"=>"")
|
||||
response = replace(response, "***"=>"")
|
||||
response = replace(response, "<|eot_id|>"=>"")
|
||||
|
||||
# check if response contain more than one functions from ["CHATBOX", "CHECKINVENTORY", "ENDCONVERSATION"]
|
||||
@@ -395,284 +393,280 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol,Any} where {T<:agen
|
||||
end
|
||||
|
||||
|
||||
""" Assigns a scalar value to each new child node to be used for selec-
|
||||
tion and backpropagation. This value effectively quantifies the agent's progress in task completion,
|
||||
serving as a heuristic to steer the search algorithm towards the most promising regions of the tree.
|
||||
# """ Assigns a scalar value to each new child node to be used for selec-
|
||||
# tion and backpropagation. This value effectively quantifies the agent's progress in task completion,
|
||||
# serving as a heuristic to steer the search algorithm towards the most promising regions of the tree.
|
||||
|
||||
# Arguments
|
||||
- `a::T1`
|
||||
one of Yiem's agent
|
||||
- `state::T2`
|
||||
a game state
|
||||
# # Arguments
|
||||
# - `a::T1`
|
||||
# one of Yiem's agent
|
||||
# - `state::T2`
|
||||
# a game state
|
||||
|
||||
# Return
|
||||
- `evaluation::Tuple{String, Integer}`
|
||||
evaluation and score
|
||||
# # Return
|
||||
# - `evaluation::Tuple{String, Integer}`
|
||||
# evaluation and score
|
||||
|
||||
# Example
|
||||
```jldoctest
|
||||
julia>
|
||||
```
|
||||
# # Example
|
||||
# ```jldoctest
|
||||
# julia>
|
||||
# ```
|
||||
|
||||
# Signature
|
||||
"""
|
||||
function evaluator(config::T1, state::T2
|
||||
)::Tuple{String,Integer} where {T1<:AbstractDict,T2<:AbstractDict}
|
||||
# # Signature
|
||||
# """
|
||||
# function evaluator(config::T1, state::T2
|
||||
# )::Tuple{String,Integer} where {T1<:AbstractDict,T2<:AbstractDict}
|
||||
|
||||
systemmsg =
|
||||
"""
|
||||
Analyze the trajectories of a solution to a question answering task. The trajectories are
|
||||
labeled by environmental observations about the situation, thoughts that can reason about
|
||||
the current situation and actions that can be three types:
|
||||
1) CHECKINVENTORY[query], which you can use to find wine in your inventory.
|
||||
2) CHATBOX[text], which you can use to interact with the user.
|
||||
# systemmsg =
|
||||
# """
|
||||
# Analyze the trajectories of a solution to a question answering task. The trajectories are
|
||||
# labeled by environmental observations about the situation, thoughts that can reason about
|
||||
# the current situation and actions that can be three types:
|
||||
# 1) CHECKINVENTORY[query], which you can use to find wine in your inventory.
|
||||
# 2) CHATBOX[text], which you can use to interact with the user.
|
||||
|
||||
Given a question and a trajectory, evaluate its correctness and provide your reasoning and
|
||||
analysis in detail. Focus on the latest thought, action, and observation. Incomplete trajectories
|
||||
can be correct if the thoughts and actions so far are correct, even if the answer is not found
|
||||
yet. Do not generate additional thoughts or actions. Then ending with the correctness score s
|
||||
where s is an integer from 0 to 10.
|
||||
# Given a question and a trajectory, evaluate its correctness and provide your reasoning and
|
||||
# analysis in detail. Focus on the latest thought, action, and observation. Incomplete trajectories
|
||||
# can be correct if the thoughts and actions so far are correct, even if the answer is not found
|
||||
# yet. Do not generate additional thoughts or actions. Then ending with the correctness score s
|
||||
# where s is an integer from 0 to 10.
|
||||
|
||||
You should only respond in JSON format as describe below:
|
||||
{"evaluation": "your evaluation", "score": "your evaluation score"}
|
||||
# You should only respond in JSON format as describe below:
|
||||
# {"evaluation": "your evaluation", "score": "your evaluation score"}
|
||||
|
||||
Here are some examples:
|
||||
user:
|
||||
{
|
||||
"question": "I'm looking for a sedan with an automatic driving feature.",
|
||||
"thought_1": "I have many types of sedans in my inventory, each with diverse features.",
|
||||
"thought_2": "But there is only 1 model that has the feature customer wanted.",
|
||||
"thought_3": "I should check our inventory first to see if we have it.",
|
||||
"action_1": {"name": "inventory", "input": "Yiem model A"},
|
||||
"observation_1": "Yiem model A is in stock."
|
||||
}
|
||||
assistant
|
||||
{
|
||||
"evaluation": "This trajectory is correct as it is reasonable to check an inventory for info provided in the question.
|
||||
It is also better to have simple searches corresponding to a single entity, making this the best action.",
|
||||
"score": 10
|
||||
}
|
||||
# Here are some examples:
|
||||
# user:
|
||||
# {
|
||||
# "question": "I'm looking for a sedan with an automatic driving feature.",
|
||||
# "thought_1": "I have many types of sedans in my inventory, each with diverse features.",
|
||||
# "thought_2": "But there is only 1 model that has the feature customer wanted.",
|
||||
# "thought_3": "I should check our inventory first to see if we have it.",
|
||||
# "action_1": {"name": "inventory", "input": "Yiem model A"},
|
||||
# "observation_1": "Yiem model A is in stock."
|
||||
# }
|
||||
# assistant
|
||||
# {
|
||||
# "evaluation": "This trajectory is correct as it is reasonable to check an inventory for info provided in the question.
|
||||
# It is also better to have simple searches corresponding to a single entity, making this the best action.",
|
||||
# "score": 10
|
||||
# }
|
||||
|
||||
user:
|
||||
{
|
||||
"question": "Do you have an all-in-one pen with 4 colors and a pencil for sale?",
|
||||
"thought_1": "Let me check our inventory first to see if I have it.",
|
||||
"action_1": {"name": "inventory", "input": "pen with 4 color and a pencil."},
|
||||
"observation_1": "I found {1: "Pilot Dr. grip 4-in-1 pen", 2: "Rotting pencil"}",
|
||||
"thought_2": "Ok, I have what the user is asking. Let's tell the user.",
|
||||
"action_2": {"name": "CHATBOX", "input": "Yes, we do have a Pilot Dr. grip 4-in-1 pen and a Rotting pencil"},
|
||||
"observation_1": "This is not what I wanted."
|
||||
}
|
||||
assistant:
|
||||
{
|
||||
"evaluation": "This trajectory is incorrect as my search term should be related to a 4-colors pen with a pencil in it,
|
||||
not a pen and a pencil seperately. A better search term should have been a 4-colors pen with a pencil, all-in-one.",
|
||||
"score": 0
|
||||
}
|
||||
# user:
|
||||
# {
|
||||
# "question": "Do you have an all-in-one pen with 4 colors and a pencil for sale?",
|
||||
# "thought_1": "Let me check our inventory first to see if I have it.",
|
||||
# "action_1": {"name": "inventory", "input": "pen with 4 color and a pencil."},
|
||||
# "observation_1": "I found {1: "Pilot Dr. grip 4-in-1 pen", 2: "Rotting pencil"}",
|
||||
# "thought_2": "Ok, I have what the user is asking. Let's tell the user.",
|
||||
# "action_2": {"name": "CHATBOX", "input": "Yes, we do have a Pilot Dr. grip 4-in-1 pen and a Rotting pencil"},
|
||||
# "observation_1": "This is not what I wanted."
|
||||
# }
|
||||
# assistant:
|
||||
# {
|
||||
# "evaluation": "This trajectory is incorrect as my search term should be related to a 4-colors pen with a pencil in it,
|
||||
# not a pen and a pencil seperately. A better search term should have been a 4-colors pen with a pencil, all-in-one.",
|
||||
# "score": 0
|
||||
# }
|
||||
|
||||
Let's begin!
|
||||
"""
|
||||
# Let's begin!
|
||||
# """
|
||||
|
||||
usermsg = """
|
||||
$(JSON3.write(state[:thoughtHistory]))
|
||||
"""
|
||||
# usermsg = """
|
||||
# $(JSON3.write(state[:thoughtHistory]))
|
||||
# """
|
||||
|
||||
chathistory =
|
||||
[
|
||||
Dict(:name => "system", :text => systemmsg),
|
||||
Dict(:name => "user", :text => usermsg)
|
||||
]
|
||||
# chathistory =
|
||||
# [
|
||||
# Dict(:name => "system", :text => systemmsg),
|
||||
# Dict(:name => "user", :text => usermsg)
|
||||
# ]
|
||||
|
||||
# put in model format
|
||||
prompt = formatLLMtext(chathistory, "llama3instruct")
|
||||
prompt *= """
|
||||
<|start_header_id|>assistant<|end_header_id|>
|
||||
{
|
||||
"""
|
||||
# # put in model format
|
||||
# prompt = GeneralUtils.formatLLMtext(_prompt; formatname="qwen")
|
||||
|
||||
pprint(prompt)
|
||||
externalService = config[:externalservice][:text2textinstruct]
|
||||
# pprint(prompt)
|
||||
# externalService = config[:externalservice][:text2textinstruct]
|
||||
|
||||
|
||||
# apply LLM specific instruct format
|
||||
externalService = config[:externalservice][:text2textinstruct]
|
||||
# # apply LLM specific instruct format
|
||||
# externalService = config[:externalservice][:text2textinstruct]
|
||||
|
||||
msgMeta = GeneralUtils.generate_msgMeta(
|
||||
externalService[:mqtttopic],
|
||||
senderName="evaluator",
|
||||
senderId=string(uuid4()),
|
||||
receiverName="text2textinstruct",
|
||||
mqttBroker=config[:mqttServerInfo][:broker],
|
||||
mqttBrokerPort=config[:mqttServerInfo][:port],
|
||||
)
|
||||
# msgMeta = GeneralUtils.generate_msgMeta(
|
||||
# externalService[:mqtttopic],
|
||||
# senderName="evaluator",
|
||||
# senderId=string(uuid4()),
|
||||
# receiverName="text2textinstruct",
|
||||
# mqttBroker=config[:mqttServerInfo][:broker],
|
||||
# mqttBrokerPort=config[:mqttServerInfo][:port],
|
||||
# )
|
||||
|
||||
outgoingMsg = Dict(
|
||||
:msgMeta => msgMeta,
|
||||
:payload => Dict(
|
||||
:text => prompt,
|
||||
:kwargs => Dict(
|
||||
:max_tokens => 512,
|
||||
:stop => ["<|eot_id|>"],
|
||||
)
|
||||
)
|
||||
)
|
||||
# outgoingMsg = Dict(
|
||||
# :msgMeta => msgMeta,
|
||||
# :payload => Dict(
|
||||
# :text => prompt,
|
||||
# :kwargs => Dict(
|
||||
# :max_tokens => 512,
|
||||
# :stop => ["<|eot_id|>"],
|
||||
# )
|
||||
# )
|
||||
# )
|
||||
|
||||
for attempt in 1:5
|
||||
try
|
||||
response = GeneralUtils.sendReceiveMqttMsg(outgoingMsg)
|
||||
_responseJsonStr = response[:response][:text]
|
||||
expectedJsonExample = """
|
||||
Here is an expected JSON format:
|
||||
{"evaluation": "...", "score": "..."}
|
||||
"""
|
||||
responseJsonStr = jsoncorrection(config, _responseJsonStr, expectedJsonExample)
|
||||
evaluationDict = copy(JSON3.read(responseJsonStr))
|
||||
# for attempt in 1:5
|
||||
# try
|
||||
# response = GeneralUtils.sendReceiveMqttMsg(outgoingMsg)
|
||||
# _responseJsonStr = response[:response][:text]
|
||||
# expectedJsonExample = """
|
||||
# Here is an expected JSON format:
|
||||
# {"evaluation": "...", "score": "..."}
|
||||
# """
|
||||
# responseJsonStr = jsoncorrection(config, _responseJsonStr, expectedJsonExample)
|
||||
# evaluationDict = copy(JSON3.read(responseJsonStr))
|
||||
|
||||
# check if dict has all required value
|
||||
dummya::AbstractString = evaluationDict[:evaluation]
|
||||
dummyb::Integer = evaluationDict[:score]
|
||||
# # check if dict has all required value
|
||||
# dummya::AbstractString = evaluationDict[:evaluation]
|
||||
# dummyb::Integer = evaluationDict[:score]
|
||||
|
||||
return (evaluationDict[:evaluation], evaluationDict[:score])
|
||||
catch e
|
||||
io = IOBuffer()
|
||||
showerror(io, e)
|
||||
errorMsg = String(take!(io))
|
||||
st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
|
||||
println("\nAttempt $attempt. Error occurred: $errorMsg\n$st ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
end
|
||||
end
|
||||
error("evaluator failed to generate an evaluation")
|
||||
end
|
||||
# return (evaluationDict[:evaluation], evaluationDict[:score])
|
||||
# catch e
|
||||
# io = IOBuffer()
|
||||
# showerror(io, e)
|
||||
# errorMsg = String(take!(io))
|
||||
# st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
|
||||
# println("\nAttempt $attempt. Error occurred: $errorMsg\n$st ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
# end
|
||||
# end
|
||||
# error("evaluator failed to generate an evaluation")
|
||||
# end
|
||||
|
||||
|
||||
"""
|
||||
# """
|
||||
|
||||
# Arguments
|
||||
# # Arguments
|
||||
|
||||
# Return
|
||||
# # Return
|
||||
|
||||
# Example
|
||||
```jldoctest
|
||||
julia>
|
||||
```
|
||||
# # Example
|
||||
# ```jldoctest
|
||||
# julia>
|
||||
# ```
|
||||
|
||||
# TODO
|
||||
- [] update docstring
|
||||
- [x] implement the function
|
||||
- [x] add try block. check result that it is expected before returning
|
||||
# # TODO
|
||||
# - [] update docstring
|
||||
# - [x] implement the function
|
||||
# - [x] add try block. check result that it is expected before returning
|
||||
|
||||
# Signature
|
||||
"""
|
||||
function reflector(config::T1, state::T2)::String where {T1<:AbstractDict,T2<:AbstractDict}
|
||||
# https://github.com/andyz245/LanguageAgentTreeSearch/blob/main/hotpot/hotpot.py
|
||||
# # Signature
|
||||
# """
|
||||
# function reflector(config::T1, state::T2)::String where {T1<:AbstractDict,T2<:AbstractDict}
|
||||
# # https://github.com/andyz245/LanguageAgentTreeSearch/blob/main/hotpot/hotpot.py
|
||||
|
||||
_prompt =
|
||||
"""
|
||||
You are a helpful sommelier working for a wine store.
|
||||
Your goal is to recommend the best wine from your inventory that match the user preferences.
|
||||
You will be given a question and a trajectory of the previous help you've done for a user.
|
||||
You were unsuccessful in helping the user either because you guessed the wrong answer with Finish[answer], or you didn't know the user enough.
|
||||
In a few sentences, Diagnose a possible reason for failure and devise a new, concise, high level plan that aims to mitigate the same failure.
|
||||
Use complete sentences.
|
||||
# _prompt =
|
||||
# """
|
||||
# You are a helpful sommelier working for a wine store.
|
||||
# Your goal is to recommend the best wine from your inventory that match the user preferences.
|
||||
# You will be given a question and a trajectory of the previous help you've done for a user.
|
||||
# You were unsuccessful in helping the user either because you guessed the wrong answer with Finish[answer], or you didn't know the user enough.
|
||||
# In a few sentences, Diagnose a possible reason for failure and devise a new, concise, high level plan that aims to mitigate the same failure.
|
||||
# Use complete sentences.
|
||||
|
||||
You should only respond in JSON format as describe below:
|
||||
{"reflection": "your relection"}
|
||||
# You should only respond in JSON format as describe below:
|
||||
# {"reflection": "your relection"}
|
||||
|
||||
Here are some examples:
|
||||
Previous Trial:
|
||||
{
|
||||
"question": "Hello, I would like a get a bottle of wine",
|
||||
"thought_1": "A customer wants to buy a bottle of wine. Before making a recommendation, I need to know more about their preferences.",
|
||||
"action_1": {"name": "CHATBOX", "input": "What is the occasion for which you're buying this wine?"},
|
||||
"observation_1": "We are holding a wedding party",
|
||||
# Here are some examples:
|
||||
# Previous Trial:
|
||||
# {
|
||||
# "question": "Hello, I would like a get a bottle of wine",
|
||||
# "thought_1": "A customer wants to buy a bottle of wine. Before making a recommendation, I need to know more about their preferences.",
|
||||
# "action_1": {"name": "CHATBOX", "input": "What is the occasion for which you're buying this wine?"},
|
||||
# "observation_1": "We are holding a wedding party",
|
||||
|
||||
"thought_2": "A wedding party, that's a great occasion! The customer might be looking for a celebratory drink. Let me ask some more questions to narrow down the options.",
|
||||
"action_2": {"name": "CHATBOX", "input": "What type of food will you be serving at the wedding?"},
|
||||
"observation_2": "It will be Thai dishes.",
|
||||
# "thought_2": "A wedding party, that's a great occasion! The customer might be looking for a celebratory drink. Let me ask some more questions to narrow down the options.",
|
||||
# "action_2": {"name": "CHATBOX", "input": "What type of food will you be serving at the wedding?"},
|
||||
# "observation_2": "It will be Thai dishes.",
|
||||
|
||||
"thought_3": "With Thai food, I should recommend a wine that complements its spicy and savory flavors. And since it's a celebratory occasion, the customer might prefer a full-bodied wine.",
|
||||
"action_3": {"name": "CHATBOX", "input": "What is your budget for this bottle of wine?"},
|
||||
"observation_3": "I would spend up to 50 bucks.",
|
||||
# "thought_3": "With Thai food, I should recommend a wine that complements its spicy and savory flavors. And since it's a celebratory occasion, the customer might prefer a full-bodied wine.",
|
||||
# "action_3": {"name": "CHATBOX", "input": "What is your budget for this bottle of wine?"},
|
||||
# "observation_3": "I would spend up to 50 bucks.",
|
||||
|
||||
"thought_4": "Now that I have some more information, it's time to narrow down the options.",
|
||||
"action_4": {"name": "winestock", "input": "red wine with full body, pairs well with spicy food, budget \$50"},
|
||||
"observation_4": "I found the following wines in our stock: \n{\n 1: El Enemigo Cabernet Franc 2019\n2: Tantara Chardonnay 2017\n\n}\n",
|
||||
# "thought_4": "Now that I have some more information, it's time to narrow down the options.",
|
||||
# "action_4": {"name": "winestock", "input": "red wine with full body, pairs well with spicy food, budget \$50"},
|
||||
# "observation_4": "I found the following wines in our stock: \n{\n 1: El Enemigo Cabernet Franc 2019\n2: Tantara Chardonnay 2017\n\n}\n",
|
||||
|
||||
"thought_5": "Now that I have a list of potential wines, I need to know more about the customer's taste preferences.",
|
||||
"action_5": {"name": "CHATBOX", "input": "What type of wine characteristics are you looking for? (e.g. tannin level, sweetness, intensity, acidity)"},
|
||||
"observation_5": "I like full-bodied red wine with low tannin.",
|
||||
# "thought_5": "Now that I have a list of potential wines, I need to know more about the customer's taste preferences.",
|
||||
# "action_5": {"name": "CHATBOX", "input": "What type of wine characteristics are you looking for? (e.g. tannin level, sweetness, intensity, acidity)"},
|
||||
# "observation_5": "I like full-bodied red wine with low tannin.",
|
||||
|
||||
"thought_6": "Now that I have more information about the customer's preferences, it's time to make a recommendation.",
|
||||
"action_6": {"name": "recommendbox", "input": "El Enemigo Cabernet Franc 2019"},
|
||||
"observation_6": "I don't like the one you recommend. I want dry wine."
|
||||
}
|
||||
# "thought_6": "Now that I have more information about the customer's preferences, it's time to make a recommendation.",
|
||||
# "action_6": {"name": "recommendbox", "input": "El Enemigo Cabernet Franc 2019"},
|
||||
# "observation_6": "I don't like the one you recommend. I want dry wine."
|
||||
# }
|
||||
|
||||
{
|
||||
"reflection": "I asked the user about the occasion, food type, and budget, and then searched for wine in the inventory right away. However, I should have asked the user for the specific wine type and their preferences in order to gather more information before making a recommendation."
|
||||
}
|
||||
# {
|
||||
# "reflection": "I asked the user about the occasion, food type, and budget, and then searched for wine in the inventory right away. However, I should have asked the user for the specific wine type and their preferences in order to gather more information before making a recommendation."
|
||||
# }
|
||||
|
||||
Let's begin!
|
||||
# Let's begin!
|
||||
|
||||
Previous trial:
|
||||
$(JSON3.write(state[:thoughtHistory]))
|
||||
{"reflection"
|
||||
"""
|
||||
# Previous trial:
|
||||
# $(JSON3.write(state[:thoughtHistory]))
|
||||
# {"reflection"
|
||||
# """
|
||||
|
||||
# apply LLM specific instruct format
|
||||
externalService = config[:externalservice][:text2textinstruct]
|
||||
llminfo = externalService[:llminfo]
|
||||
prompt =
|
||||
if llminfo[:name] == "llama3instruct"
|
||||
formatLLMtext_llama3instruct("system", _prompt)
|
||||
else
|
||||
error("llm model name is not defied yet $(@__LINE__)")
|
||||
end
|
||||
# # apply LLM specific instruct format
|
||||
# externalService = config[:externalservice][:text2textinstruct]
|
||||
# llminfo = externalService[:llminfo]
|
||||
# prompt =
|
||||
# if llminfo[:name] == "llama3instruct"
|
||||
# formatLLMtext_llama3instruct("system", _prompt)
|
||||
# else
|
||||
# error("llm model name is not defied yet $(@__LINE__)")
|
||||
# end
|
||||
|
||||
msgMeta = GeneralUtils.generate_msgMeta(
|
||||
a.config[:externalservice][:text2textinstruct][:mqtttopic],
|
||||
senderName="reflector",
|
||||
senderId=string(uuid4()),
|
||||
receiverName="text2textinstruct",
|
||||
mqttBroker=config[:mqttServerInfo][:broker],
|
||||
mqttBrokerPort=config[:mqttServerInfo][:port],
|
||||
)
|
||||
# msgMeta = GeneralUtils.generate_msgMeta(
|
||||
# a.config[:externalservice][:text2textinstruct][:mqtttopic],
|
||||
# senderName="reflector",
|
||||
# senderId=string(uuid4()),
|
||||
# receiverName="text2textinstruct",
|
||||
# mqttBroker=config[:mqttServerInfo][:broker],
|
||||
# mqttBrokerPort=config[:mqttServerInfo][:port],
|
||||
# )
|
||||
|
||||
outgoingMsg = Dict(
|
||||
:msgMeta => msgMeta,
|
||||
:payload => Dict(
|
||||
:text => prompt,
|
||||
:kwargs => Dict(
|
||||
:max_tokens => 512,
|
||||
:stop => ["<|eot_id|>"],
|
||||
)
|
||||
)
|
||||
)
|
||||
# outgoingMsg = Dict(
|
||||
# :msgMeta => msgMeta,
|
||||
# :payload => Dict(
|
||||
# :text => prompt,
|
||||
# :kwargs => Dict(
|
||||
# :max_tokens => 512,
|
||||
# :stop => ["<|eot_id|>"],
|
||||
# )
|
||||
# )
|
||||
# )
|
||||
|
||||
for attempt in 1:5
|
||||
try
|
||||
response = GeneralUtils.sendReceiveMqttMsg(outgoingMsg)
|
||||
_responseJsonStr = response[:response][:text]
|
||||
expectedJsonExample = """
|
||||
Here is an expected JSON format:
|
||||
{"reflection": "..."}
|
||||
"""
|
||||
responseJsonStr = jsoncorrection(config, _responseJsonStr, expectedJsonExample)
|
||||
reflectionDict = copy(JSON3.read(responseJsonStr))
|
||||
# for attempt in 1:5
|
||||
# try
|
||||
# response = GeneralUtils.sendReceiveMqttMsg(outgoingMsg)
|
||||
# _responseJsonStr = response[:response][:text]
|
||||
# expectedJsonExample = """
|
||||
# Here is an expected JSON format:
|
||||
# {"reflection": "..."}
|
||||
# """
|
||||
# responseJsonStr = jsoncorrection(config, _responseJsonStr, expectedJsonExample)
|
||||
# reflectionDict = copy(JSON3.read(responseJsonStr))
|
||||
|
||||
# check if dict has all required value
|
||||
dummya::AbstractString = reflectionDict[:reflection]
|
||||
# # check if dict has all required value
|
||||
# dummya::AbstractString = reflectionDict[:reflection]
|
||||
|
||||
return reflectionDict[:reflection]
|
||||
catch e
|
||||
io = IOBuffer()
|
||||
showerror(io, e)
|
||||
errorMsg = String(take!(io))
|
||||
st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
|
||||
println("\nAttempt $attempt. Error occurred: $errorMsg\n$st ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
end
|
||||
end
|
||||
error("reflector failed to generate a thought")
|
||||
end
|
||||
# return reflectionDict[:reflection]
|
||||
# catch e
|
||||
# io = IOBuffer()
|
||||
# showerror(io, e)
|
||||
# errorMsg = String(take!(io))
|
||||
# st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
|
||||
# println("\nAttempt $attempt. Error occurred: $errorMsg\n$st ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
# end
|
||||
# end
|
||||
# error("reflector failed to generate a thought")
|
||||
# end
|
||||
|
||||
|
||||
""" Chat with llm.
|
||||
@@ -864,46 +858,6 @@ function think(a::T)::NamedTuple{(:actionname, :result),Tuple{String,String}} wh
|
||||
)
|
||||
result = chatresponse
|
||||
|
||||
# # store thoughtDict after the conversation finish
|
||||
# if a.memory[:events][end][:thought][:action_name] == "ENDCONVERSATION"
|
||||
# # generateSituationReport in the agent didn't include the last conversation
|
||||
# # so the function will be called here
|
||||
# a.memory[:recap] = generateSituationReport(a, a.func[:text2textInstructLLM]; skiprecent=0)
|
||||
|
||||
# for (i, event) in enumerate(a.memory[:events])
|
||||
# if event[:subject] == "assistant"
|
||||
# # create timeline of the last 3 conversation except the last one.
|
||||
# # The former will be used as caching key and the latter will be the caching target
|
||||
# # in vector database
|
||||
# all_recapkeys = keys(a.memory[:recap]) # recap as caching
|
||||
# all_recapkeys_vec = [r for r in all_recapkeys] # convert to a vector
|
||||
|
||||
# # select from 1 to 2nd-to-lase event (i.e. excluding the latest which is assistant's response)
|
||||
# _recapkeys_vec = all_recapkeys_vec[1:i-1]
|
||||
|
||||
# # select only previous 3 recaps
|
||||
# recapkeys_vec =
|
||||
# if length(_recapkeys_vec) <= 3 # 1st message is a user's hello msg
|
||||
# _recapkeys_vec # choose all
|
||||
# else
|
||||
# _recapkeys_vec[end-2:end]
|
||||
# end
|
||||
# #[PENDING] if there is specific data such as number, donot store in database
|
||||
# tempmem = DataStructures.OrderedDict()
|
||||
# for k in recapkeys_vec
|
||||
# tempmem[k] = a.memory[:recap][k]
|
||||
# end
|
||||
|
||||
# recap = GeneralUtils.dictToString_noKey(tempmem)
|
||||
# thoughtDict = a.memory[:events][i][:thought] # latest assistant thoughtDict
|
||||
# a.func[:insertSommelierDecision](recap, thoughtDict)
|
||||
# else
|
||||
# # skip
|
||||
# end
|
||||
# end
|
||||
# println("Caching conversation done")
|
||||
# end
|
||||
|
||||
elseif actionname == "CHECKINVENTORY"
|
||||
if rawresponse !== nothing
|
||||
vd = GeneralUtils.dfToVectorDict(rawresponse)
|
||||
@@ -1040,10 +994,7 @@ function generatechat(a::sommelier, thoughtDict)
|
||||
]
|
||||
|
||||
# put in model format
|
||||
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct")
|
||||
prompt *= """
|
||||
<|start_header_id|>assistant<|end_header_id|>
|
||||
"""
|
||||
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="qwen")
|
||||
|
||||
try
|
||||
response = a.func[:text2textInstructLLM](prompt)
|
||||
@@ -1170,10 +1121,7 @@ function generatechat(a::companion)
|
||||
]
|
||||
|
||||
# put in model format
|
||||
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct")
|
||||
prompt *= """
|
||||
<|start_header_id|>assistant<|end_header_id|>
|
||||
"""
|
||||
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="qwen")
|
||||
|
||||
response = a.text2textInstructLLM(prompt)
|
||||
|
||||
@@ -1342,10 +1290,7 @@ function generatequestion(a, text2textInstructLLM::Function; recent=nothing)::St
|
||||
]
|
||||
|
||||
# put in model format
|
||||
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct")
|
||||
prompt *= """
|
||||
<|start_header_id|>assistant<|end_header_id|>
|
||||
"""
|
||||
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="qwen")
|
||||
|
||||
try
|
||||
response = text2textInstructLLM(prompt)
|
||||
@@ -1448,6 +1393,9 @@ function generateSituationReport(a, text2textInstructLLM::Function; skiprecent::
|
||||
Let's begin!
|
||||
"""
|
||||
|
||||
header = ["Event_$i:" for i in eachindex(a.memory[:events])]
|
||||
dictkey = lowercase.(["Event_$i" for i in eachindex(a.memory[:events])])
|
||||
|
||||
if length(a.memory[:events]) <= skiprecent
|
||||
return nothing
|
||||
end
|
||||
@@ -1473,14 +1421,9 @@ function generateSituationReport(a, text2textInstructLLM::Function; skiprecent::
|
||||
]
|
||||
|
||||
# put in model format
|
||||
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct")
|
||||
prompt *= """
|
||||
<|start_header_id|>assistant<|end_header_id|>
|
||||
"""
|
||||
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="qwen")
|
||||
|
||||
response = text2textInstructLLM(prompt)
|
||||
header = ["Event_$i:" for i in eachindex(a.memory[:events])]
|
||||
dictkey = lowercase.(["Event_$i" for i in eachindex(a.memory[:events])])
|
||||
responsedict = GeneralUtils.textToDict(response, header;
|
||||
dictKey=dictkey, symbolkey=true)
|
||||
|
||||
@@ -1531,10 +1474,7 @@ function detectWineryName(a, text)
|
||||
]
|
||||
|
||||
# put in model format
|
||||
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="llama3instruct")
|
||||
prompt *= """
|
||||
<|start_header_id|>assistant<|end_header_id|>
|
||||
"""
|
||||
prompt = GeneralUtils.formatLLMtext(_prompt; formatname="qwen")
|
||||
|
||||
try
|
||||
response = a.func[:text2textInstructLLM](prompt)
|
||||
|
||||
Reference in New Issue
Block a user