diff --git a/src/interface.jl b/src/interface.jl index c9f0ff0..423dd65 100755 --- a/src/interface.jl +++ b/src/interface.jl @@ -2,7 +2,7 @@ module interface export agent, addNewMessage, clearMessage, removeLatestMsg, generatePrompt_tokenPrefix, - generatePrompt_tokenSuffix + generatePrompt_tokenSuffix, conversation using JSON3, DataStructures, Dates, UUIDs using CommUtils @@ -35,12 +35,14 @@ using CommUtils # @kwdef mutable struct agent - availableRole=["system", "user", "assistant"] - agentName::String="assistant" - maxUserMsg::Int= 10 - earlierConversation::String="" # summary of earlier conversation - thoughts::String= "" # internal thinking area - mqttClient::Union{mqttClient, Nothing}= nothing + availableRole = ["system", "user", "assistant"] + agentName::String = "assistant" + maxUserMsg::Int = 10 + earlierConversation::String = "" # summary of earlier conversation + mqttClient::Union{mqttClient, Nothing} = nothing + msgMeta::Union{Dict, Nothing} = nothing + + thought::String = "" # internal thinking area """ Dict(Role=> Content) ; Role can be system, user, assistant Example: @@ -50,14 +52,27 @@ using CommUtils Dict(:role=>"user", :content=> "Hello, how are you"), ] """ - # Ref: Chat prompt format https://huggingface.co/TheBloke/Llama-2-7B-Chat-GGML/discussions/3 - messages= [Dict(:role=>"system", :content=> "You are a helpful assistant.", :timestamp=> Dates.now()),] + + # # Ref: Chat prompt format https://huggingface.co/TheBloke/Llama-2-7B-Chat-GGML/discussions/3 + # messages= [Dict(:role=>"system", :content=> "You are a helpful assistant.", :timestamp=> Dates.now()),] end function agent( agentName::String, systemMessage::String, # system message of an agent mqttClientSpec::Tuple; + msgMeta::Dict=Dict( + :msgPurpose=> "updateStatus", + :from=> "chatbothub", + :to=> "llmAI", + :requestrespond=> "request", + :sendto=> "", # destination topic + :replyTo=> "chatbothub/llm/respond", # requester ask responder to send reply to this topic + :repondToMsgId=> "", # responder is responding to this msg id + :taskstatus=> "", # "complete", "fail", "waiting" or other status + :timestamp=> Dates.now(), + :msgId=> "$(uuid4())", + ), availableRole::AbstractArray=["system", "user", "assistant"], maxUserMsg::Int=10,) @@ -66,7 +81,7 @@ function agent( newAgent.maxUserMsg= maxUserMsg systemMessage= "Your name is $agentName. " * systemMessage newAgent.messages= [Dict(:role=>"system", :content=> systemMessage, :timestamp=> Dates.now()),] - newAgent.mqttClient= mqttClient(mqttClientSpec) + newAgent.mqttClient= CommUtils.mqttClient(mqttClientSpec) return newAgent end @@ -186,14 +201,127 @@ function generatePrompt_tokenPrefix(a::agent; return prompt end +#WORKING +function conversation(a::agent, usermsg::String) + userIntent = identifyUserIntention(a, usermsg) + @show userIntent + + +end + +#WORKING +function identifyUserIntention(a::agent, usermsg::String) + identify_usermsg = + """ + You are to determine intention of the question. + Your choices are: + chat: normal conversation that you don't need to do something. + task: a request for you to do something. + + Here are examples of how to determine intention of the question: + Question: How are you? + Answer: {chat}, this question intention is about chat. + + Question: Ummm. + Answer: {chat}, this question is about chat. + + Question: Search for the stock prices of 'BJC' and 'IOU'on June 10th. + Answer: {task}, this question is about asking you to do something. + + Question: Hello + Answer: {chat}, this question is about chat. + + Question: 'BJC' and 'IOU'on June 10th. + Answer: {task}, this question is about asking you to do something. + + Question: What time is it? + Answer: {task}, this question is about asking you to do something. + + Question: What is the price of 'ABC' + Answer: {task}, this question is about asking you to do something. + + Question: Do you like coconut? + Answer: {task}, this question is about asking you to do something. + + Question: What is the weather tomorrow? + Answer: {task}, this question is about asking you to do something. + + Question: I'm fine. + Answer: {chat}, this question is about chat. + + Question: How to make a cake? + Answer: {task}, this question is about asking you to do something. + + Question: Did you turn off the light? + Answer: {task}, this question is about asking you to do something. + + Question: What is stock price of Tesla on June 6th? + Answer: {task}, this question is about asking you to do something. + + Question: Tell me some jokes. + Answer: {chat}, this question is about chat. + + Begin! + + Question: {input} + """ + + identify_usermsg = replace(identifymsgPrompt, "{input}" => usermsg) + + msg = Dict( + :msgMeta=> a.msgMeta, + :txt=> identifymsgPrompt, + ) + + payloadChannel = Channel(1) + + # send prompt + CommUtils.request(a.mqttClient, msg, pubtopic=a.mqttClient.pubtopic.llmAIgpu) + starttime = Dates.now() + timeout = 10 + result = nothing + + while true + timepass = (Dates.now() - starttime).value / 1000.0 + CommUtils.mqttRun(mqttclient, payloadChannel) + if isready(payloadChannel) + topic, payload = take!(payloadChannel) + if payload[:msgMeta][:repondToMsgId] == msgPrompt[:msgMeta][:msgId] + result = payload[:txt] + break + end + elseif timepass <= timeout + # skip, within waiting period + elseif timepass > timeout + result = nothing + break + else + error("undefined condition $(@__LINE__)") + end + end + + answer = getStringBetweenCharacters(result, "{", "}") + + return answer +end +function getStringBetweenCurlyBraces(s::AbstractString) + m = match(r"\{(.+?)\}", s) + m = m == "" ? "" : m.captures[1] + return m +end - - - - +function getStringBetweenCharacters(text::AbstractString, startChar::String, endChar::String) + startIndex= findlast(startChar, text) + endIndex= findlast(endChar, text) + if startIndex === nothing || endIndex === nothing + return nothing + else + return text[startIndex.stop+1: endIndex.start-1] + end +end