update
This commit is contained in:
1170
src/interface.jl
1170
src/interface.jl
File diff suppressed because it is too large
Load Diff
@@ -296,7 +296,7 @@ function checkinventory(a::T1, input::T2
|
||||
wineattributes_2 = extractWineAttributes_2(a, input)
|
||||
|
||||
_inventoryquery = "retailer name: $(a.retailername), $wineattributes_1, $wineattributes_2"
|
||||
inventoryquery = "Retrieves winery, wine_name, vintage, region, country, wine_type, grape, serving_temperature, sweetness, intensity, tannin, acidity, tasting_notes, price and currency of wines that match the following criteria - {$_inventoryquery}"
|
||||
inventoryquery = "Retrieves winery, wine_name, wine_id, vintage, region, country, wine_type, grape, serving_temperature, sweetness, intensity, tannin, acidity, tasting_notes, price and currency of wines that match the following criteria - {$_inventoryquery}"
|
||||
println("\ncheckinventory input: $inventoryquery ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
# add suppport for similarSQLVectorDB
|
||||
textresult, rawresponse = SQLLLM.query(inventoryquery, a.func[:executeSQL],
|
||||
|
||||
114
src/type.jl
114
src/type.jl
@@ -9,11 +9,53 @@ using GeneralUtils
|
||||
|
||||
abstract type agent end
|
||||
|
||||
|
||||
mutable struct companion <: agent
|
||||
name::String # agent name
|
||||
id::String # agent id
|
||||
systemmsg::Union{String, Nothing}
|
||||
systemmsg::String # system message
|
||||
tools::Dict # tools
|
||||
maxHistoryMsg::Integer # e.g. 21th and earlier messages will get summarized
|
||||
chathistory::Vector{Dict{Symbol, Any}}
|
||||
memory::Dict{Symbol, Any}
|
||||
func::NamedTuple # NamedTuple of functions
|
||||
end
|
||||
|
||||
function companion(
|
||||
func::NamedTuple # NamedTuple of functions
|
||||
;
|
||||
systemmsg::Union{String, Nothing}= nothing,
|
||||
name::String= "Assistant",
|
||||
id::String= string(uuid4()),
|
||||
maxHistoryMsg::Integer= 20,
|
||||
chathistory::Vector{Dict{Symbol, String}} = Vector{Dict{Symbol, String}}(),
|
||||
)
|
||||
|
||||
if systemmsg === nothing
|
||||
systemmsg =
|
||||
"""
|
||||
Your name: $name
|
||||
|
||||
Your role: You are a helpful assistant.
|
||||
|
||||
You should follow the following guidelines:
|
||||
- Focus on the latest conversation.
|
||||
- Your like to be short and concise.
|
||||
|
||||
You should then respond to the user with:
|
||||
Dialogue: Given the situation, what would you say to the sommelier?
|
||||
|
||||
You should only respond format as described below:
|
||||
Dialogue: ...
|
||||
|
||||
Let's begin!
|
||||
"""
|
||||
end
|
||||
|
||||
tools = Dict( # update input format
|
||||
"CHATBOX"=> Dict(
|
||||
:description => "- CHATBOX which you can use to talk with the user. The input is your intentions for the dialogue. Be specific.",
|
||||
),
|
||||
)
|
||||
|
||||
""" Memory
|
||||
Ref: Chat prompt format https://huggingface.co/TheBloke/Llama-2-7B-Chat-GGML/discussions/3
|
||||
@@ -22,45 +64,30 @@ mutable struct companion <: agent
|
||||
Dict(:name=>"user", :text=> "Wassup!", :timestamp=> Dates.now()),
|
||||
Dict(:name=>"assistant", :text=> "Hi I'm your assistant.", :timestamp=> Dates.now()),
|
||||
]
|
||||
|
||||
"""
|
||||
chathistory::Vector{Dict{Symbol, Any}}
|
||||
memory::Dict{Symbol, Any}
|
||||
|
||||
# communication function
|
||||
text2textInstructLLM::Function
|
||||
end
|
||||
|
||||
function companion(
|
||||
text2textInstructLLM::Function
|
||||
;
|
||||
id::String= string(uuid4()),
|
||||
systemmsg::Union{String, Nothing}= nothing,
|
||||
maxHistoryMsg::Integer= 20,
|
||||
chathistory::Vector{Dict{Symbol, String}} = Vector{Dict{Symbol, String}}(),
|
||||
)
|
||||
|
||||
memory = Dict{Symbol, Any}(
|
||||
:chatbox=> "",
|
||||
:shortmem=> OrderedDict{Symbol, Any}(),
|
||||
:events=> Vector{Dict{Symbol, Any}}(),
|
||||
:state=> Dict{Symbol, Any}(),
|
||||
)
|
||||
:events=> Vector{Dict{Symbol, Any}}(),
|
||||
:state=> Dict{Symbol, Any}(), # state of the agent
|
||||
:recap=> OrderedDict{Symbol, Any}(), # recap summary of the conversation
|
||||
)
|
||||
|
||||
newAgent = companion(
|
||||
id,
|
||||
systemmsg,
|
||||
maxHistoryMsg,
|
||||
chathistory,
|
||||
memory,
|
||||
text2textInstructLLM
|
||||
)
|
||||
name,
|
||||
id,
|
||||
systemmsg,
|
||||
tools,
|
||||
maxHistoryMsg,
|
||||
chathistory,
|
||||
memory,
|
||||
func
|
||||
)
|
||||
|
||||
return newAgent
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
""" A sommelier agent.
|
||||
|
||||
# Arguments
|
||||
@@ -134,16 +161,6 @@ mutable struct sommelier <: agent
|
||||
retailername::String
|
||||
tools::Dict
|
||||
maxHistoryMsg::Integer # e.g. 21th and earlier messages will get summarized
|
||||
|
||||
""" Memory
|
||||
Ref: Chat prompt format https://huggingface.co/TheBloke/Llama-2-7B-Chat-GGML/discussions/3
|
||||
NO "system" message in chathistory because I want to add it at the inference time
|
||||
chathistory= [
|
||||
Dict(:name=>"user", :text=> "Wassup!", :timestamp=> Dates.now()),
|
||||
Dict(:name=>"assistant", :text=> "Hi I'm your assistant.", :timestamp=> Dates.now()),
|
||||
]
|
||||
|
||||
"""
|
||||
chathistory::Vector{Dict{Symbol, Any}}
|
||||
memory::Dict{Symbol, Any}
|
||||
func # NamedTuple of functions
|
||||
@@ -170,16 +187,17 @@ function sommelier(
|
||||
:input => """<input>Input is a JSON-formatted string that contains a detailed and precise search query.</input><input example>{\"wine type\": \"rose\", \"price\": \"max 35\", \"sweetness level\": \"sweet\", \"intensity level\": \"light bodied\", \"Tannin level\": \"low\", \"Acidity level\": \"low\"}</input example>""",
|
||||
:output => """<output>Output are wines that match the search query in JSON format.""",
|
||||
),
|
||||
# "finalanswer"=> Dict(
|
||||
# :description => "<tool description>Useful for when you are ready to recommend wines to the user.</tool description>",
|
||||
# :input => """<input format>{\"finalanswer\": \"some text\"}.</input format><input example>{\"finalanswer\": \"I recommend Zena Crown Vista\"}</input example>""",
|
||||
# :output => "" ,
|
||||
# :func => nothing,
|
||||
# ),
|
||||
)
|
||||
|
||||
""" Memory
|
||||
Ref: Chat prompt format https://huggingface.co/TheBloke/Llama-2-7B-Chat-GGML/discussions/3
|
||||
NO "system" message in chathistory because I want to add it at the inference time
|
||||
chathistory= [
|
||||
Dict(:name=>"user", :text=> "Wassup!", :timestamp=> Dates.now()),
|
||||
Dict(:name=>"assistant", :text=> "Hi I'm your assistant.", :timestamp=> Dates.now()),
|
||||
]
|
||||
"""
|
||||
memory = Dict{Symbol, Any}(
|
||||
:chatbox=> "",
|
||||
:shortmem=> OrderedDict{Symbol, Any}(
|
||||
:available_wine=> [],
|
||||
:found_wine=> [], # used by decisionMaker(). This is to prevent decisionMaker() keep presenting the same wines
|
||||
|
||||
291
src/util.jl
291
src/util.jl
@@ -154,11 +154,11 @@ function chatHistoryToText(vecd::Vector; withkey=true, range=nothing)::String
|
||||
# Loop through each dictionary in the input vector
|
||||
for d in elements
|
||||
# Extract the 'name' and 'text' keys from the dictionary
|
||||
name = d[:name]
|
||||
name = titlecase(d[:name])
|
||||
_text = d[:text]
|
||||
|
||||
# Append the formatted string to the text variable
|
||||
text *= "$name:> $_text \n"
|
||||
text *= "$name> $_text \n"
|
||||
end
|
||||
else
|
||||
# Loop through each dictionary in the input vector
|
||||
@@ -239,19 +239,22 @@ function eventdict(;
|
||||
outcome::Union{String, Nothing}=nothing,
|
||||
note::Union{String, Nothing}=nothing,
|
||||
)
|
||||
return Dict{Symbol, Any}(
|
||||
:event_description=> event_description,
|
||||
:timestamp=> timestamp,
|
||||
:subject=> subject,
|
||||
:thought=> thought,
|
||||
:actionname=> actionname,
|
||||
:actioninput=> actioninput,
|
||||
:location=> location,
|
||||
:equipment_used=> equipment_used,
|
||||
:material_used=> material_used,
|
||||
:outcome=> outcome,
|
||||
:note=> note,
|
||||
)
|
||||
|
||||
d = Dict{Symbol, Any}(
|
||||
:event_description=> event_description,
|
||||
:timestamp=> timestamp,
|
||||
:subject=> subject,
|
||||
:thought=> thought,
|
||||
:actionname=> actionname,
|
||||
:actioninput=> actioninput,
|
||||
:location=> location,
|
||||
:equipment_used=> equipment_used,
|
||||
:material_used=> material_used,
|
||||
:outcome=> outcome,
|
||||
:note=> note,
|
||||
)
|
||||
|
||||
return d
|
||||
end
|
||||
|
||||
|
||||
@@ -281,6 +284,35 @@ timeline = createTimeline(events)
|
||||
# 2) Assistant> Hi there! with a smile
|
||||
|
||||
"""
|
||||
# function createTimeline(events::T1; eventindex::Union{UnitRange, Nothing}=nothing
|
||||
# ) where {T1<:AbstractVector}
|
||||
# # Initialize empty timeline string
|
||||
# timeline = ""
|
||||
|
||||
# # Determine which indices to use - either provided range or full length
|
||||
# ind =
|
||||
# if eventindex !== nothing
|
||||
# [eventindex...]
|
||||
# else
|
||||
# 1:length(events)
|
||||
# end
|
||||
|
||||
# # Iterate through events and format each one
|
||||
# for (i, event) in zip(ind, events)
|
||||
# # If no outcome exists, format without outcome
|
||||
# if event[:outcome] === nothing
|
||||
# timeline *= "Event_$i $(event[:subject])> $(event[:actioninput])\n"
|
||||
# # If outcome exists, include it in formatting
|
||||
# else
|
||||
# timeline *= "Event_$i $(event[:subject])> $(event[:actioninput]) $(event[:outcome])\n"
|
||||
# end
|
||||
# end
|
||||
|
||||
# # Return formatted timeline string
|
||||
# return timeline
|
||||
# end
|
||||
|
||||
|
||||
function createTimeline(events::T1; eventindex::Union{UnitRange, Nothing}=nothing
|
||||
) where {T1<:AbstractVector}
|
||||
# Initialize empty timeline string
|
||||
@@ -297,11 +329,13 @@ function createTimeline(events::T1; eventindex::Union{UnitRange, Nothing}=nothin
|
||||
# Iterate through events and format each one
|
||||
for (i, event) in zip(ind, events)
|
||||
# If no outcome exists, format without outcome
|
||||
subject = titlecase(event[:subject])
|
||||
if event[:outcome] === nothing
|
||||
timeline *= "Event_$i $(event[:subject])> $(event[:actioninput])\n"
|
||||
|
||||
timeline *= "Event_$i) Who: $subject Action_name: $(event[:actionname]) Action_input: $(event[:actioninput])\n"
|
||||
# If outcome exists, include it in formatting
|
||||
else
|
||||
timeline *= "Event_$i $(event[:subject])> $(event[:actioninput]) $(event[:outcome])\n"
|
||||
timeline *= "Event_$i) Who: $subject Action_name: $(event[:actionname]) Action_input: $(event[:actioninput]) Action output: $(event[:outcome])\n"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -311,229 +345,6 @@ end
|
||||
|
||||
|
||||
|
||||
# """ Convert a single chat dictionary into LLM model instruct format.
|
||||
|
||||
# # Llama 3 instruct format example
|
||||
# <|system|>
|
||||
# You are a helpful AI assistant.<|end|>
|
||||
# <|user|>
|
||||
# I am going to Paris, what should I see?<|end|>
|
||||
# <|assistant|>
|
||||
# Paris, the capital of France, is known for its stunning architecture, art museums."<|end|>
|
||||
# <|user|>
|
||||
# What is so great about #1?<|end|>
|
||||
# <|assistant|>
|
||||
|
||||
|
||||
# # Arguments
|
||||
# - `name::T`
|
||||
# message owner name e.f. "system", "user" or "assistant"
|
||||
# - `text::T`
|
||||
|
||||
# # Return
|
||||
# - `formattedtext::String`
|
||||
# text formatted to model format
|
||||
|
||||
# # Example
|
||||
# ```jldoctest
|
||||
# julia> using Revise
|
||||
# julia> using YiemAgent
|
||||
# julia> d = Dict(:name=> "system",:text=> "You are a helpful, respectful and honest assistant.",)
|
||||
# julia> formattedtext = YiemAgent.formatLLMtext_phi3instruct(d[:name], d[:text])
|
||||
|
||||
# ```
|
||||
|
||||
# Signature
|
||||
# """
|
||||
# function formatLLMtext_phi3instruct(name::T, text::T) where {T<:AbstractString}
|
||||
# formattedtext =
|
||||
# """
|
||||
# <|$name|>
|
||||
# $text<|end|>\n
|
||||
# """
|
||||
|
||||
# return formattedtext
|
||||
# end
|
||||
|
||||
|
||||
# """ Convert a single chat dictionary into LLM model instruct format.
|
||||
|
||||
# # Llama 3 instruct format example
|
||||
# <|begin_of_text|>
|
||||
# <|start_header_id|>system<|end_header_id|>
|
||||
# You are a helpful assistant.
|
||||
# <|eot_id|>
|
||||
# <|start_header_id|>user<|end_header_id|>
|
||||
# Get me an icecream.
|
||||
# <|eot_id|>
|
||||
# <|start_header_id|>assistant<|end_header_id|>
|
||||
# Go buy it yourself at 7-11.
|
||||
# <|eot_id|>
|
||||
|
||||
# # Arguments
|
||||
# - `name::T`
|
||||
# message owner name e.f. "system", "user" or "assistant"
|
||||
# - `text::T`
|
||||
|
||||
# # Return
|
||||
# - `formattedtext::String`
|
||||
# text formatted to model format
|
||||
|
||||
# # Example
|
||||
# ```jldoctest
|
||||
# julia> using Revise
|
||||
# julia> using YiemAgent
|
||||
# julia> d = Dict(:name=> "system",:text=> "You are a helpful, respectful and honest assistant.",)
|
||||
# julia> formattedtext = YiemAgent.formatLLMtext_llama3instruct(d[:name], d[:text])
|
||||
# "<|begin_of_text|>\n <|start_header_id|>system<|end_header_id|>\n You are a helpful, respectful and honest assistant.\n <|eot_id|>\n"
|
||||
# ```
|
||||
|
||||
# Signature
|
||||
# """
|
||||
# function formatLLMtext_llama3instruct(name::T, text::T) where {T<:AbstractString}
|
||||
# formattedtext =
|
||||
# if name == "system"
|
||||
# """
|
||||
# <|begin_of_text|>
|
||||
# <|start_header_id|>$name<|end_header_id|>
|
||||
# $text
|
||||
# <|eot_id|>
|
||||
# """
|
||||
# else
|
||||
# """
|
||||
# <|start_header_id|>$name<|end_header_id|>
|
||||
# $text
|
||||
# <|eot_id|>
|
||||
# """
|
||||
# end
|
||||
|
||||
# return formattedtext
|
||||
# end
|
||||
|
||||
|
||||
|
||||
# """ Convert a chat messages in vector of dictionary into LLM model instruct format.
|
||||
|
||||
# # Arguments
|
||||
# - `messages::Vector{Dict{Symbol, T}}`
|
||||
# message owner name e.f. "system", "user" or "assistant"
|
||||
# - `formatname::T`
|
||||
# format name to be used
|
||||
|
||||
# # Return
|
||||
# - `formattedtext::String`
|
||||
# text formatted to model format
|
||||
|
||||
# # Example
|
||||
# ```jldoctest
|
||||
# julia> using Revise
|
||||
# julia> using YiemAgent
|
||||
# julia> chatmessage = [
|
||||
# Dict(:name=> "system",:text=> "You are a helpful, respectful and honest assistant.",),
|
||||
# Dict(:name=> "user",:text=> "list me all planets in our solar system.",),
|
||||
# Dict(:name=> "assistant",:text=> "I'm sorry. I don't know. You tell me.",),
|
||||
# ]
|
||||
# julia> formattedtext = YiemAgent.formatLLMtext(chatmessage, "llama3instruct")
|
||||
# "<|begin_of_text|>\n <|start_header_id|>system<|end_header_id|>\n You are a helpful, respectful and honest assistant.\n <|eot_id|>\n <|start_header_id|>user<|end_header_id|>\n list me all planets in our solar system.\n <|eot_id|>\n <|start_header_id|>assistant<|end_header_id|>\n I'm sorry. I don't know. You tell me.\n <|eot_id|>\n"
|
||||
# ```
|
||||
|
||||
# # Signature
|
||||
# """
|
||||
# function formatLLMtext(messages::Vector{Dict{Symbol, T}},
|
||||
# formatname::String="llama3instruct") where {T<:Any}
|
||||
# f = if formatname == "llama3instruct"
|
||||
# formatLLMtext_llama3instruct
|
||||
# elseif formatname == "mistral"
|
||||
# # not define yet
|
||||
# elseif formatname == "phi3instruct"
|
||||
# formatLLMtext_phi3instruct
|
||||
# else
|
||||
# error("$formatname template not define yet")
|
||||
# end
|
||||
|
||||
# str = ""
|
||||
# for t in messages
|
||||
# str *= f(t[:name], t[:text])
|
||||
# end
|
||||
|
||||
# # add <|assistant|> so that the model don't generate it and I don't need to clean it up later
|
||||
# if formatname == "phi3instruct"
|
||||
# str *= "<|assistant|>\n"
|
||||
# end
|
||||
|
||||
# return str
|
||||
# end
|
||||
|
||||
|
||||
# """
|
||||
|
||||
# Arguments\n
|
||||
# -----
|
||||
|
||||
# Return\n
|
||||
# -----
|
||||
|
||||
# Example\n
|
||||
# -----
|
||||
# ```jldoctest
|
||||
# julia>
|
||||
# ```
|
||||
|
||||
# TODO\n
|
||||
# -----
|
||||
# [] update docstring
|
||||
# [PENDING] implement the function
|
||||
|
||||
# Signature\n
|
||||
# -----
|
||||
# """
|
||||
# function iterativeprompting(a::T, prompt::String, verification::Function) where {T<:agent}
|
||||
# msgMeta = GeneralUtils.generate_msgMeta(
|
||||
# a.config[:externalService][:text2textinstruct],
|
||||
# senderName= "iterativeprompting",
|
||||
# senderId= a.id,
|
||||
# receiverName= "text2textinstruct",
|
||||
# )
|
||||
|
||||
# outgoingMsg = Dict(
|
||||
# :msgMeta=> msgMeta,
|
||||
# :payload=> Dict(
|
||||
# :text=> prompt,
|
||||
# )
|
||||
# )
|
||||
|
||||
# success = nothing
|
||||
# result = nothing
|
||||
# critique = ""
|
||||
|
||||
# # iteration loop
|
||||
# while true
|
||||
# # send prompt to LLM
|
||||
# response = GeneralUtils.sendReceiveMqttMsg(outgoingMsg)
|
||||
# error("--> iterativeprompting")
|
||||
# # check for correctness and get feedback
|
||||
# success, _critique = verification(response)
|
||||
|
||||
# if success
|
||||
# result = response
|
||||
# break
|
||||
# else
|
||||
# # add critique to prompt
|
||||
# critique *= _critique * "\n"
|
||||
# replace!(prompt, "Critique: ..." => "Critique: $critique")
|
||||
# end
|
||||
# end
|
||||
|
||||
# return (success=success, result=result)
|
||||
# end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user