update
This commit is contained in:
+25
-23
@@ -12,9 +12,9 @@ using ..type, ..util, ..llmfunction
|
|||||||
"""
|
"""
|
||||||
Private agent loop. Runs in a background `@spawn` task.
|
Private agent loop. Runs in a background `@spawn` task.
|
||||||
|
|
||||||
Waits on `input_ch` and `followUpQueue`, processing whichever has a message first.
|
Waits on `inputChannel` and `followUpChannel`, processing whichever has a message first.
|
||||||
On each iteration, dispatches the message through `_process_message` and sends the result
|
On each iteration, dispatches the message through `_process_message` and sends the result
|
||||||
to `output_ch`. Exits on `:shutdown` signal.
|
to `outputChannel`. Exits on `:shutdown` signal.
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `agent::yiemAgent`: The agent whose loop to run
|
- `agent::yiemAgent`: The agent whose loop to run
|
||||||
@@ -25,22 +25,26 @@ to `output_ch`. Exits on `:shutdown` signal.
|
|||||||
# Notes
|
# Notes
|
||||||
- This function is automatically spawned as a background task when a `yiemAgent` is created.
|
- This function is automatically spawned as a background task when a `yiemAgent` is created.
|
||||||
- On any error, logs the error with `@error` and exits the loop.
|
- On any error, logs the error with `@error` and exits the loop.
|
||||||
- Message priority: `input_ch` messages are checked before `followUpQueue` messages.
|
- Message priority: `inputChannel` messages are checked before `followUpChannel` messages.
|
||||||
|
|
||||||
# Examples
|
# Examples
|
||||||
```jldoctest
|
```jldoctest
|
||||||
julia> # Called automatically by yiemAgent constructor
|
julia> # Called automatically by yiemAgent constructor
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
function _agent_loop(agent::yiemAgent) #WORKING
|
function _agent_loop(agent::yiemAgent)
|
||||||
try
|
try
|
||||||
while true
|
while true
|
||||||
# Wait on either channel — the one with a message fires first
|
# Wait on either channel — the one with a message fires first
|
||||||
# Wait on either channel — the one with a message is taken first
|
# Wait on either channel — the one with a message is taken first
|
||||||
msg = nothing
|
msg = nothing
|
||||||
while msg === nothing
|
while msg === nothing
|
||||||
if isready(agent.input_ch)
|
if isready(agent.inputChannel)
|
||||||
msg = take!(agent.input_ch)
|
msg = take!(agent.inputChannel)
|
||||||
|
|
||||||
|
#TODO convert raw user msg to userMessage type
|
||||||
|
|
||||||
|
#TODO add userMessage to agent._state.messages
|
||||||
else
|
else
|
||||||
yield()
|
yield()
|
||||||
end
|
end
|
||||||
@@ -52,20 +56,19 @@ function _agent_loop(agent::yiemAgent) #WORKING
|
|||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
#TODO convert raw user msg to userMessage type
|
# Dispatch message through the processing pipeline
|
||||||
|
|
||||||
#TODO add userMessage to agent._state.messages
|
|
||||||
|
|
||||||
|
|
||||||
if isready(agent.followUpQueue)
|
|
||||||
msg = take!(agent.followUpQueue)
|
|
||||||
end
|
|
||||||
|
|
||||||
# @spawn. Dispatch message through the processing pipeline.
|
|
||||||
result = _process_message(agent, msg)
|
result = _process_message(agent, msg)
|
||||||
|
|
||||||
# Send response to user
|
|
||||||
put!(agent.output_ch, result)
|
|
||||||
|
# check followUp message. if there are, add them all to agent.inputChannel
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Send response to user if no user message in both agent.inputChannel and agent.followUpChannel,
|
||||||
|
# output the result
|
||||||
|
put!(agent.outputChannel, result)
|
||||||
end
|
end
|
||||||
catch e
|
catch e
|
||||||
# On any error, send error response and exit the loop
|
# On any error, send error response and exit the loop
|
||||||
@@ -73,6 +76,7 @@ function _agent_loop(agent::yiemAgent) #WORKING
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Process a single message through the agent pipeline.
|
Process a single message through the agent pipeline.
|
||||||
|
|
||||||
@@ -81,7 +85,7 @@ should be implemented. Currently a placeholder that echoes back the received mes
|
|||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `agent::yiemAgent`: The agent processing the message
|
- `agent::yiemAgent`: The agent processing the message
|
||||||
- `msg`: The message to process (from `input_ch` or `followUpQueue`)
|
- `msg`: The message to process (from `inputChannel` or `followUpChannel`)
|
||||||
|
|
||||||
# Returns
|
# Returns
|
||||||
- An `assistantMessage` instance with the processed response
|
- An `assistantMessage` instance with the processed response
|
||||||
@@ -102,14 +106,12 @@ julia> # Currently returns a placeholder echo response
|
|||||||
"""
|
"""
|
||||||
function _process_message(agent::yiemAgent, msg)
|
function _process_message(agent::yiemAgent, msg)
|
||||||
# WORKING Replace with actual processing logic
|
# WORKING Replace with actual processing logic
|
||||||
# check steering message
|
|
||||||
|
while (# )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 1. call agent.
|
|
||||||
# 2. Call agent.formatMsgForLLM(agent._state) to format for LLM
|
# 2. Call agent.formatMsgForLLM(agent._state) to format for LLM
|
||||||
# 3. If preprocessMessages is set, call agent.preprocessMessages(...)
|
# 3. If preprocessMessages is set, call agent.preprocessMessages(...)
|
||||||
# 4. Call the LLM (blocking — the task waits here)
|
# 4. Call the LLM (blocking — the task waits here)
|
||||||
|
|||||||
+10
-10
@@ -15,7 +15,7 @@ using ..type, ..util, ..llmfunction
|
|||||||
Send a message to the agent's input channel.
|
Send a message to the agent's input channel.
|
||||||
|
|
||||||
Blocks if the input channel buffer is full (capacity 16 by default).
|
Blocks if the input channel buffer is full (capacity 16 by default).
|
||||||
The agent processes messages from `input_ch` in the background task.
|
The agent processes messages from `inputChannel` in the background task.
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `agent::yiemAgent`: The agent instance to send a message to
|
- `agent::yiemAgent`: The agent instance to send a message to
|
||||||
@@ -35,7 +35,7 @@ yiemAgent(...)
|
|||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
function run_agent(agent::yiemAgent, msg)
|
function run_agent(agent::yiemAgent, msg)
|
||||||
put!(agent.input_ch, msg)
|
put!(agent.inputChannel, msg)
|
||||||
return agent
|
return agent
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -60,13 +60,13 @@ assistantMessage(...)
|
|||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
function take_response(agent::yiemAgent)
|
function take_response(agent::yiemAgent)
|
||||||
return take!(agent.output_ch)
|
return take!(agent.outputChannel)
|
||||||
end
|
end
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Send a follow-up message while the agent is still processing.
|
Send a follow-up message while the agent is still processing.
|
||||||
|
|
||||||
Follow-up messages are queued and processed after all `input_ch` messages
|
Follow-up messages are queued and processed after all `inputChannel` messages
|
||||||
and before any tool call results are sent.
|
and before any tool call results are sent.
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
@@ -88,7 +88,7 @@ yiemAgent(...)
|
|||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
function follow_up(agent::yiemAgent, msg)
|
function follow_up(agent::yiemAgent, msg)
|
||||||
put!(agent.followUpQueue, msg)
|
put!(agent.followUpChannel, msg)
|
||||||
return agent
|
return agent
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ end
|
|||||||
Gracefully stop the agent.
|
Gracefully stop the agent.
|
||||||
|
|
||||||
Sends a `:shutdown` signal to the input channel, waits for the background task to finish,
|
Sends a `:shutdown` signal to the input channel, waits for the background task to finish,
|
||||||
then closes all channels (`input_ch`, `output_ch`, `followUpQueue`).
|
then closes all channels (`inputChannel`, `outputChannel`, `followUpChannel`).
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `agent::yiemAgent`: The agent instance to stop
|
- `agent::yiemAgent`: The agent instance to stop
|
||||||
@@ -115,7 +115,7 @@ julia> stop_agent(agent)
|
|||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
function stop_agent(agent::yiemAgent)
|
function stop_agent(agent::yiemAgent)
|
||||||
put!(agent.input_ch, :shutdown)
|
put!(agent.inputChannel, :shutdown)
|
||||||
try
|
try
|
||||||
fetch(agent._task)
|
fetch(agent._task)
|
||||||
catch e
|
catch e
|
||||||
@@ -123,9 +123,9 @@ function stop_agent(agent::yiemAgent)
|
|||||||
rethrow(e)
|
rethrow(e)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
close(agent.input_ch)
|
close(agent.inputChannel)
|
||||||
close(agent.output_ch)
|
close(agent.outputChannel)
|
||||||
close(agent.followUpQueue)
|
close(agent.followUpChannel)
|
||||||
return nothing
|
return nothing
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+11
-12
@@ -353,18 +353,17 @@ docstring
|
|||||||
mutable struct yiemAgent <: agent # High-level agent wrapper
|
mutable struct yiemAgent <: agent # High-level agent wrapper
|
||||||
_state::agentState # Current state (prompt, model, messages, tools, etc.)
|
_state::agentState # Current state (prompt, model, messages, tools, etc.)
|
||||||
|
|
||||||
input_ch::Channel # user sends prompt message to agent.
|
inputChannel::Channel # user sends prompt message to agent.
|
||||||
# if agent is idle, it process user message right away.
|
# if agent is idle, it process user message right away.
|
||||||
# if agent is running, it process user message after
|
# if agent is running, it process user message after
|
||||||
# the current tool call finished.
|
# the current tool call finished.
|
||||||
|
|
||||||
followUpQueue::Channel # Messages queued via follow_up() during agent is
|
followUpChannel::Channel # Buffers messages the user sends while the agent is busy.
|
||||||
# running. After the agent loop process all input_ch
|
# Processed after all inputChannel messages are handled
|
||||||
# and the agent isn't using tool call, it processes
|
# and the agent is idle (not using a tool call).
|
||||||
# followUp messages
|
|
||||||
|
|
||||||
output_ch::Channel # agent sends response message to user after processing
|
outputChannel::Channel # agent sends response message to user after processing
|
||||||
# all user messages in input_ch and all followUp messages.
|
# all user messages in inputChannel and all followUp messages.
|
||||||
|
|
||||||
_task::Union{Task, Nothing} # Background task running the agent loop
|
_task::Union{Task, Nothing} # Background task running the agent loop
|
||||||
|
|
||||||
@@ -383,7 +382,7 @@ end
|
|||||||
Create a new yiemAgent instance with a background loop task.
|
Create a new yiemAgent instance with a background loop task.
|
||||||
|
|
||||||
Spawns a background `@spawn` task that runs the agent loop, listening
|
Spawns a background `@spawn` task that runs the agent loop, listening
|
||||||
on `input_ch` and `followUpQueue` channels concurrently.
|
on `inputChannel` and `followUpChannel` channels concurrently.
|
||||||
|
|
||||||
# Keyword Arguments
|
# Keyword Arguments
|
||||||
- `systemPrompt::String`: System prompt for the agent
|
- `systemPrompt::String`: System prompt for the agent
|
||||||
@@ -425,16 +424,16 @@ function yiemAgent(
|
|||||||
toolExecution=nothing,
|
toolExecution=nothing,
|
||||||
)
|
)
|
||||||
# Create channels: input (user -> agent), followUp (async queue), output (agent -> user)
|
# Create channels: input (user -> agent), followUp (async queue), output (agent -> user)
|
||||||
input_ch = Channel(16)
|
inputChannel = Channel(16)
|
||||||
followUp = Channel(32)
|
followUp = Channel(32)
|
||||||
output_ch = Channel(16)
|
outputChannel = Channel(16)
|
||||||
|
|
||||||
# Create struct with a placeholder task, then spawn and replace it
|
# Create struct with a placeholder task, then spawn and replace it
|
||||||
agent = yiemAgent(
|
agent = yiemAgent(
|
||||||
agentState(systemPrompt, model, tools, messages),
|
agentState(systemPrompt, model, tools, messages),
|
||||||
input_ch,
|
inputChannel,
|
||||||
followUp,
|
followUp,
|
||||||
output_ch,
|
outputChannel,
|
||||||
nothing, # placeholder — replaced below
|
nothing, # placeholder — replaced below
|
||||||
formatMsgForLLM,
|
formatMsgForLLM,
|
||||||
preprocessMessages,
|
preprocessMessages,
|
||||||
|
|||||||
Reference in New Issue
Block a user