This commit is contained in:
narawat lamaiin
2024-04-17 07:49:02 +07:00
parent 673c64b223
commit bcd525a7d9
3 changed files with 271 additions and 91 deletions

View File

@@ -1,6 +1,6 @@
module interface module interface
export addNewMessage export addNewMessage, conversation
using JSON3, DataStructures, Dates, UUIDs, HTTP, Random using JSON3, DataStructures, Dates, UUIDs, HTTP, Random
using GeneralUtils using GeneralUtils
@@ -33,64 +33,89 @@ using ..type, ..util, ..llmfunction
# ---------------------------------------------- 100 --------------------------------------------- # # ---------------------------------------------- 100 --------------------------------------------- #
""" Chat with llm.
""" Add new message to agent.
Arguments\n Arguments\n
----- -----
a::agent a::agent
an agent an agent
role::String
message sender role i.e. system, user or assistant
text::String
message text
Return\n Return\n
----- -----
nothing None
Example\n Example\n
----- -----
```jldoctest ```jldoctest
julia> using YiemAgent, MQTTClient, GeneralUtils julia> using JSON3, UUIDs, Dates, FileIO, MQTTClient, ChatAgent
julia> client, connection = MakeConnection("test.mosquitto.org", 1883) julia> const mqttBroker = "mqtt.yiem.cc"
julia> connect(client, connection) julia> mqttclient, connection = MakeConnection(mqttBroker, 1883)
julia> msgMeta = GeneralUtils.generate_msgMeta("testtopic") julia> tools=Dict( # update input format
julia> agentConfig = Dict( "askbox"=>Dict(
:receiveprompt=>Dict( :description => "<askbox tool description>Useful for when you need to ask the user for more context. Do not ask the user their own question.</askbox tool description>",
:mqtttopic=> "testtopic/receive", :input => "<input>Input is a text in JSON format.</input><input example>{\"Q1\": \"How are you doing?\", \"Q2\": \"How may I help you?\"}</input example>",
), :output => "" ,
:receiveinternal=>Dict( :func => nothing,
:mqtttopic=> "testtopic/internal", ),
), )
:text2text=>Dict( julia> msgMeta = Dict(
:mqtttopic=> "testtopic/text2text", :msgPurpose=> "updateStatus",
), :from=> "agent",
) :to=> "llmAI",
julia> a = YiemAgent.sommelier( :requestresponse=> "request",
client, :sendto=> "", # destination topic
msgMeta, :replyTo=> "agent/api/v0.1.0/txt/response", # requester ask responseer to send reply to this topic
agentConfig, :repondToMsgId=> "", # responseer is responseing to this msg id
) :taskstatus=> "", # "complete", "fail", "waiting" or other status
julia> YiemAgent.addNewMessage(a, "user", "hello") :timestamp=> Dates.now(),
:msgId=> "$(uuid4())",
)
julia> a = ChatAgent.agentReflex(
"Jene",
mqttclient,
msgMeta,
agentConfigTopic, # I need a function to send msg to config topic to get load balancer
role=:sommelier,
tools=tools
)
julia> newAgent = ChatAgent.agentReact(agent)
julia> response = ChatAgent.conversation(newAgent, "Hi! how are you?")
``` ```
Signature\n Signature\n
----- -----
""" """
function addNewMessage(a::T1, role::String, text::T2; function conversation(a::agentReflex, usermsg::String; attemptlimit::Int=3)
maximumMsg::Integer=20) where {T1<:agent, T2<:AbstractString} a.attemptlimit = attemptlimit
if role ["system", "user", "assistant"] # guard against typo workstate = nothing
error("role is not in agent.availableRole $(@__LINE__)") response = nothing
_ = addNewMessage(a, "user", usermsg)
isuseplan = isUsePlans(a)
# newinfo = extractinfo(a, usermsg)
# a.env = newinfo !== nothing ? updateEnvState(a, newinfo) : a.env
@show isuseplan
if isuseplan # use plan before responding
if haskey(a.memory[:shortterm], "User:") == false #TODO should change role if user want to buy wine.
a.memory[:shortterm]["User:"] = usermsg
end
workstate, response = work(a)
end end
#TODO summarize the oldest 10 message # if LLM using askbox, use returning msg form askbox as conversation response
if length(a.chathistory) > maximumMsg if workstate == "askbox" || workstate == "formulatedUserResponse"
summarize(a.chathistory) #TODO paraphrase msg so that it is human friendlier word.
else else
d = Dict(:role=> role, :text=> text, :timestamp=> Dates.now()) response = chat_mistral_openorca(a)
push!(a.chathistory, d) response = split(response, "\n\n")[1]
response = split(response, "\n\n")[1]
end end
response = removeTrailingCharacters(response)
_ = addNewMessage(a, "assistant", response)
return response
end end
@@ -100,4 +125,53 @@ end
end # module interface end # module interface

View File

@@ -1,6 +1,6 @@
module type module type
export agent, sommelier, clearhistory export agent, sommelier
using Dates, UUIDs, DataStructures, JSON3 using Dates, UUIDs, DataStructures, JSON3
using GeneralUtils using GeneralUtils
@@ -165,56 +165,6 @@ function sommelier(
return newAgent return newAgent
end end
""" Clear agent chat history.
Arguments\n
-----
a::agent
an agent
Return\n
-----
nothing
Example\n
-----
```jldoctest
julia> using YiemAgent, MQTTClient, GeneralUtils
julia> client, connection = MakeConnection("test.mosquitto.org", 1883)
julia> connect(client, connection)
julia> msgMeta = GeneralUtils.generate_msgMeta("testtopic")
julia> agentConfig = Dict(
:receiveprompt=>Dict(
:mqtttopic=> "testtopic/receive",
),
:receiveinternal=>Dict(
:mqtttopic=> "testtopic/internal",
),
:text2text=>Dict(
:mqtttopic=> "testtopic/text2text",
),
)
julia> a = YiemAgent.sommelier(
client,
msgMeta,
agentConfig,
)
julia> YiemAgent.addNewMessage(a, "user", "hello")
julia> YiemAgent.clearhistory(a)
```
Signature\n
-----
"""
function clearhistory(a::T) where {T<:agent}
empty!(a.chathistory)
empty!(a.mctstree)
empty!(a.plan[:activeplan])
empty!(a.plan[:currenttrajectory])
end

View File

@@ -1,12 +1,168 @@
module util module util
# export sendReceivePrompt export clearhistory, addNewMessage
using UUIDs, Dates, DataStructures, HTTP, MQTTClient, JSON3 using UUIDs, Dates, DataStructures, HTTP, MQTTClient, JSON3
using GeneralUtils using GeneralUtils
using ..type using ..type
# ---------------------------------------------- 100 --------------------------------------------- # # ---------------------------------------------- 100 --------------------------------------------- #
""" Clear agent chat history.
Arguments\n
-----
a::agent
an agent
Return\n
-----
nothing
Example\n
-----
```jldoctest
julia> using YiemAgent, MQTTClient, GeneralUtils
julia> client, connection = MakeConnection("test.mosquitto.org", 1883)
julia> connect(client, connection)
julia> msgMeta = GeneralUtils.generate_msgMeta("testtopic")
julia> agentConfig = Dict(
:receiveprompt=>Dict(
:mqtttopic=> "testtopic/receive",
),
:receiveinternal=>Dict(
:mqtttopic=> "testtopic/internal",
),
:text2text=>Dict(
:mqtttopic=> "testtopic/text2text",
),
)
julia> a = YiemAgent.sommelier(
client,
msgMeta,
agentConfig,
)
julia> YiemAgent.addNewMessage(a, "user", "hello")
julia> YiemAgent.clearhistory(a)
```
Signature\n
-----
"""
function clearhistory(a::T) where {T<:agent}
empty!(a.chathistory)
empty!(a.mctstree)
empty!(a.plan[:activeplan])
empty!(a.plan[:currenttrajectory])
end
""" Add new message to agent.
Arguments\n
-----
a::agent
an agent
role::String
message sender role i.e. system, user or assistant
text::String
message text
Return\n
-----
nothing
Example\n
-----
```jldoctest
julia> using YiemAgent, MQTTClient, GeneralUtils
julia> client, connection = MakeConnection("test.mosquitto.org", 1883)
julia> connect(client, connection)
julia> msgMeta = GeneralUtils.generate_msgMeta("testtopic")
julia> agentConfig = Dict(
:receiveprompt=>Dict(
:mqtttopic=> "testtopic/receive",
),
:receiveinternal=>Dict(
:mqtttopic=> "testtopic/internal",
),
:text2text=>Dict(
:mqtttopic=> "testtopic/text2text",
),
)
julia> a = YiemAgent.sommelier(
client,
msgMeta,
agentConfig,
)
julia> YiemAgent.addNewMessage(a, "user", "hello")
```
Signature\n
-----
"""
function addNewMessage(a::T1, role::String, text::T2;
maximumMsg::Integer=20) where {T1<:agent, T2<:AbstractString}
if role ["system", "user", "assistant"] # guard against typo
error("role is not in agent.availableRole $(@__LINE__)")
end
#TODO summarize the oldest 10 message
if length(a.chathistory) > maximumMsg
summarize(a.chathistory)
else
d = Dict(:role=> role, :text=> text, :timestamp=> Dates.now())
push!(a.chathistory, d)
end
end