update
This commit is contained in:
+175
-39
@@ -1,15 +1,11 @@
|
||||
module type
|
||||
export agent, sommelier, companion, virtualcustomer, agentContext, yiemAgent,
|
||||
export agentContext, yiemAgent,
|
||||
run_agent, take_response, follow_up, stop_agent
|
||||
|
||||
|
||||
using Dates, UUIDs, DataStructures, JSON, NATS
|
||||
using GeneralUtils
|
||||
|
||||
# ============================================================================
|
||||
# Simple type aliases / definitions
|
||||
# ============================================================================
|
||||
|
||||
const Timestamp = DateTime
|
||||
|
||||
struct Usage
|
||||
@@ -17,12 +13,10 @@ struct Usage
|
||||
outputTokens::Int64
|
||||
end
|
||||
|
||||
# ---------------------------------------------- 100 --------------------------------------------- #
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Message types
|
||||
# ============================================================================
|
||||
# ------------------------------------------------------------------------------------------------ #
|
||||
# Message types #
|
||||
# ------------------------------------------------------------------------------------------------ #
|
||||
abstract type agentMessage end # Base type for all agent messages
|
||||
|
||||
struct userMessage <: agentMessage # Message from the user
|
||||
@@ -135,9 +129,9 @@ function toolResultMessage(; role="tool", toolCallId="", toolName="",
|
||||
end
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Message content types
|
||||
# ============================================================================
|
||||
# ------------------------------------------------------------------------------------------------ #
|
||||
# Message content types #
|
||||
# ------------------------------------------------------------------------------------------------ #
|
||||
|
||||
abstract type messageContent end # Base type for message content
|
||||
|
||||
@@ -190,9 +184,9 @@ function imageContent(; data="", mimeType="")
|
||||
end
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Tool types
|
||||
# ============================================================================
|
||||
# ------------------------------------------------------------------------------------------------ #
|
||||
# Tool types #
|
||||
# ------------------------------------------------------------------------------------------------ #
|
||||
|
||||
"""
|
||||
A tool available to the agent.
|
||||
@@ -220,9 +214,9 @@ struct agentTool{TParameters, TDetails} # A tool available to the agent
|
||||
end
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Agent context
|
||||
# ============================================================================
|
||||
# ------------------------------------------------------------------------------------------------ #
|
||||
# Agent context #
|
||||
# ------------------------------------------------------------------------------------------------ #
|
||||
|
||||
"""
|
||||
Snapshot of the agent's conversation context.
|
||||
@@ -242,15 +236,18 @@ struct agentContext # Snapshot of the agent's conversa
|
||||
end
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Agent state
|
||||
# ============================================================================
|
||||
# ------------------------------------------------------------------------------------------------ #
|
||||
# Agent state #
|
||||
# ------------------------------------------------------------------------------------------------ #
|
||||
|
||||
mutable struct agentState # Mutable runtime state of an agent
|
||||
systemPrompt::String # System prompt text
|
||||
model::llmModel # LLM model to use
|
||||
tools::Vector{agentTool} # Available tools
|
||||
messages::Vector{agentMessage} # Conversation messages
|
||||
|
||||
# messages history includes userMessage, assistantMessage, toolResultMessage
|
||||
messages::Vector{agentMessage}
|
||||
|
||||
pendingToolCalls::Vector{String} # Tool call IDs waiting for results
|
||||
activeRun::Bool # is agent processing user message?
|
||||
errorMessage::Union{String, Nothing} # Last error message
|
||||
@@ -343,9 +340,148 @@ struct llmModel{Api} # LLM model configuration
|
||||
maxTokens::Int64 # Maximum output tokens per completion
|
||||
end
|
||||
|
||||
# ============================================================================
|
||||
# Agent struct
|
||||
# ============================================================================
|
||||
# ------------------------------------------------------------------------------------------------ #
|
||||
# Agent loop configuration & tool execution types #
|
||||
# ------------------------------------------------------------------------------------------------ #
|
||||
|
||||
"""
|
||||
Configuration for the agent tool execution loop.
|
||||
|
||||
# Arguments
|
||||
- `tools::Vector{agentTool}`: Available tools
|
||||
- `beforeToolCall::Union{Function, Nothing}`: Callback before tool execution
|
||||
- `afterToolCall::Union{Function, Nothing}`: Callback after tool execution
|
||||
- `toolExecution::String`: Execution mode — "sequential" or "parallel"
|
||||
"""
|
||||
struct agentLoopConfig
|
||||
tools::Vector{agentTool}
|
||||
beforeToolCall::Union{Function, Nothing}
|
||||
afterToolCall::Union{Function, Nothing}
|
||||
toolExecution::String
|
||||
end
|
||||
|
||||
"""
|
||||
Signal for aborting ongoing operations.
|
||||
|
||||
# Arguments
|
||||
- `aborted::Bool`: Whether the operation has been aborted
|
||||
"""
|
||||
struct abortSignal
|
||||
aborted::Bool
|
||||
end
|
||||
|
||||
"""
|
||||
Result returned by tool execution before the `afterToolCall` hook.
|
||||
|
||||
# Arguments
|
||||
- `content::Vector{messageContent}`: Tool output content
|
||||
- `details::Dict{Any,Any}`: Tool-specific details
|
||||
- `usage::Union{Usage, Nothing}`: Token usage if applicable
|
||||
- `terminate::Bool`: Whether tool requests termination of the agent loop
|
||||
"""
|
||||
struct agentToolResult
|
||||
content::Vector{messageContent}
|
||||
details::Dict{Any,Any}
|
||||
usage::Union{Usage, Nothing}
|
||||
terminate::Bool
|
||||
end
|
||||
|
||||
"""
|
||||
Function type for parallel execution override on a tool.
|
||||
|
||||
# Arguments
|
||||
- Context for parallel execution
|
||||
|
||||
# Returns
|
||||
- `agentToolCallBatch`: The result batch from parallel execution
|
||||
"""
|
||||
const toolparallelExecute = Function
|
||||
|
||||
"""
|
||||
Context passed to the `beforeToolCall` hook.
|
||||
|
||||
# Arguments
|
||||
- `message::assistantMessage`: The assistant message containing the tool call
|
||||
- `toolCall::agentToolCall`: The tool call being prepared
|
||||
- `args::Dict{String,Any}`: Validated tool arguments
|
||||
- `context::agentContext`: Current conversation context
|
||||
"""
|
||||
struct assistantMsgCtx
|
||||
message::assistantMessage
|
||||
toolCall::agentToolCall
|
||||
args::Dict{String,Any}
|
||||
context::agentContext
|
||||
end
|
||||
|
||||
"""
|
||||
Context passed to the `afterToolCall` hook.
|
||||
|
||||
# Arguments
|
||||
- `message::assistantMessage`: The assistant message containing the tool call
|
||||
- `toolCall::agentToolCall`: The tool call that was executed
|
||||
- `args::Dict{String,Any}`: Tool arguments
|
||||
- `result::agentToolResult`: The raw tool result
|
||||
- `isError::Bool`: Whether execution resulted in an error
|
||||
- `context::agentContext`: Current conversation context
|
||||
"""
|
||||
struct afterCtx
|
||||
message::assistantMessage
|
||||
toolCall::agentToolCall
|
||||
args::Dict{String,Any}
|
||||
result::agentToolResult
|
||||
isError::Bool
|
||||
context::agentContext
|
||||
end
|
||||
|
||||
"""
|
||||
Event emitted when a tool call execution starts.
|
||||
|
||||
# Arguments
|
||||
- `toolCallId::String`: ID of the tool call
|
||||
- `toolName::String`: Name of the tool
|
||||
- `arguments::Dict{String,Any}`: Tool arguments
|
||||
"""
|
||||
struct toolExecStartEvent
|
||||
toolCallId::String
|
||||
toolName::String
|
||||
arguments::Dict{String,Any}
|
||||
end
|
||||
|
||||
"""
|
||||
Event emitted with partial results during tool execution.
|
||||
|
||||
# Arguments
|
||||
- `toolCallId::String`: ID of the tool call
|
||||
- `toolName::String`: Name of the tool
|
||||
- `arguments::Dict{String,Any}`: Tool arguments
|
||||
- `partialResult::Any`: The partial result data
|
||||
"""
|
||||
struct toolExecUpdateEvent
|
||||
toolCallId::String
|
||||
toolName::String
|
||||
arguments::Dict{String,Any}
|
||||
partialResult::Any
|
||||
end
|
||||
|
||||
"""
|
||||
Event emitted when a tool call execution ends.
|
||||
|
||||
# Arguments
|
||||
- `toolCallId::String`: ID of the tool call
|
||||
- `toolName::String`: Name of the tool
|
||||
- `result::agentToolResult`: The final tool result
|
||||
- `isError::Bool`: Whether execution resulted in an error
|
||||
"""
|
||||
struct toolExecEndEvent
|
||||
toolCallId::String
|
||||
toolName::String
|
||||
result::agentToolResult
|
||||
isError::Bool
|
||||
end
|
||||
|
||||
# ------------------------------------------------------------------------------------------------ #
|
||||
# Agent struct #
|
||||
# ------------------------------------------------------------------------------------------------ #
|
||||
|
||||
abstract type agent end
|
||||
|
||||
@@ -367,14 +503,14 @@ mutable struct yiemAgent <: agent # High-level agent wrapper
|
||||
# and all followUp messages.
|
||||
outputChannel::Channel
|
||||
|
||||
_task::Union{Task, Nothing} # Background task running the agent loop
|
||||
_agent_loop::Union{Task, Nothing} # agent loop running in the background
|
||||
|
||||
# Preprocess/transform messages and context (modify, filter, prune, inject context from memory,
|
||||
# reorder, ...) for a single LLM call in _process_message()'s loop.
|
||||
# returns new Vector{agentMessage}
|
||||
preprocessContext ::Union{Function, Nothing}
|
||||
prepareContext ::Union{Function, Nothing}
|
||||
|
||||
# Convert preprocessContext()'s new Vector{agentMessage} to LLM message format
|
||||
# Convert prepareContext()'s new Vector{agentMessage} to LLM message format
|
||||
formatMsgForLLM::Function
|
||||
|
||||
# Actually invoke the LLM to get a completion response. The LLM response comes back as an
|
||||
@@ -391,8 +527,8 @@ mutable struct yiemAgent <: agent # High-level agent wrapper
|
||||
# Callback invoked after executing a tool call to sanitize tools output so the output is ready
|
||||
# to be converted into toolResults message
|
||||
afterToolCall::Union{Function, Nothing}
|
||||
prepareNextTurn::Union{Function, Nothing} # Callback to prepare the next conversation turn
|
||||
prepareNextTurnWithContext::Union{Function, Nothing} # Same but receives context
|
||||
# prepareNextTurn::Union{Function, Nothing} # Callback to prepare the next conversation turn
|
||||
# prepareNextTurnWithContext::Union{Function, Nothing} # Same but receives context
|
||||
sessionId::Union{String, Nothing} # Optional session identifier
|
||||
maxRetryDelayMs::Union{Int64, Nothing} # Maximum delay between retries (ms)
|
||||
parallelToolExecute::Bool # Default: false
|
||||
@@ -412,7 +548,7 @@ on `inputChannel` and `followUpChannel` channels concurrently.
|
||||
- `messages::Vector{agentMessage}`: Initial conversation messages (default: empty)
|
||||
- `formatMsgForLLM::Function`: Convert agent messages to LLM message format (default: `defaultformatMsgForLLM`)
|
||||
- `llmCall::Function`: Function to invoke the LLM (required)
|
||||
- `preprocessContext::Union{Function, Nothing}`: Preprocess/transform messages before sending to LLM (default: `nothing`)
|
||||
- `prepareContext::Union{Function, Nothing}`: Preprocess/transform messages before sending to LLM (default: `nothing`)
|
||||
- `beforeToolCall::Union{Function, Nothing}`: Callback invoked before executing a tool call (default: `nothing`)
|
||||
- `afterToolCall::Union{Function, Nothing}`: Callback invoked after executing a tool call (default: `nothing`)
|
||||
- `prepareNextTurn::Union{Function, Nothing}`: Callback to prepare the next conversation turn (default: `nothing`)
|
||||
@@ -436,13 +572,13 @@ function yiemAgent(
|
||||
model=nothing,
|
||||
tools::Vector{agentTool}=agentTool[],
|
||||
messages::Vector{agentMessage}=agentMessage[],
|
||||
preprocessContext::Union{Function, Nothing}=nothing,
|
||||
prepareContext::Union{Function, Nothing}=nothing,
|
||||
formatMsgForLLM::Function=defaultformatMsgForLLM,
|
||||
llmCall::Function,
|
||||
beforeToolCall::Union{Function, Nothing}=nothing,
|
||||
afterToolCall::Union{Function, Nothing}=nothing,
|
||||
prepareNextTurn::Union{Function, Nothing}=nothing,
|
||||
prepareNextTurnWithContext::Union{Function, Nothing}=nothing,
|
||||
# prepareNextTurn::Union{Function, Nothing}=nothing,
|
||||
# prepareNextTurnWithContext::Union{Function, Nothing}=nothing,
|
||||
sessionId::Union{String, Nothing}=nothing,
|
||||
maxRetryDelayMs::Union{Int64, Nothing}=nothing,
|
||||
parallelToolExecute::Bool=false,
|
||||
@@ -460,13 +596,13 @@ function yiemAgent(
|
||||
followUp,
|
||||
outputChannel,
|
||||
nothing, # placeholder — replaced below
|
||||
preprocessContext,
|
||||
prepareContext,
|
||||
formatMsgForLLM,
|
||||
llmCall,
|
||||
beforeToolCall,
|
||||
afterToolCall,
|
||||
prepareNextTurn,
|
||||
prepareNextTurnWithContext,
|
||||
# prepareNextTurn,
|
||||
# prepareNextTurnWithContext,
|
||||
sessionId,
|
||||
maxRetryDelayMs,
|
||||
parallelToolExecute,
|
||||
@@ -474,7 +610,7 @@ function yiemAgent(
|
||||
)
|
||||
|
||||
# Spawn the background loop and attach it
|
||||
agent._task = @spawn _agent_loop(agent)
|
||||
agent._agent_loop = @spawn _agent_loop(agent)
|
||||
|
||||
return agent
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user