This commit is contained in:
2026-07-31 08:08:03 +07:00
parent 8d5c661562
commit c9a7661e93
+39 -31
View File
@@ -78,9 +78,9 @@ agentLoop(prompts, context, config, signal, stream_fn)
```julia ```julia
runAgentLoop(prompts, context, config, emit, signal, stream_fn) runAgentLoop(prompts, context, config, emit, signal, stream_fn)
-> new_messages = copy(prompts) # [UserMessage(...)] -> new_messages = copy(prompts) # [UserMessage(...)]
-> current_context = AgentContext(context.system_prompt, [UserMessage(...)], context.tools) -> current_context = AgentContext(context.system_prompt, vcat(context.messages, copy(prompts)), context.tools)
-> emit(AgentStartEvent()) -> emit(AgentStartEvent())
-> emit(TurnStartEvent()) -> emit(TurnStartEvent())
-> for prompt in prompts: emit(MessageStartEvent(prompt)); emit(MessageEndEvent(prompt)) end -> for prompt in prompts: emit(MessageStartEvent(prompt)); emit(MessageEndEvent(prompt)) end
-> runLoop(current_context, new_messages, config, signal, emit, stream_fn) -> runLoop(current_context, new_messages, config, signal, emit, stream_fn)
@@ -98,10 +98,10 @@ Events emitted so far:
```julia ```julia
runLoop(initial_context, new_messages, initial_config, signal, emit, stream_function) runLoop(initial_context, new_messages, initial_config, signal, emit, stream_function)
-> current_context = AgentContext(system_prompt, [UserMessage(...)], tools) -> current_context = initial_context
-> first_turn = true -> first_turn = true
-> pending_messages = [] -> pending_messages = getSteeringMessages(config) # may be empty [] by default (agent_loop.jl:180-182)
-> while true: -> while true:
has_more_tool_calls = true # reset each outer iteration has_more_tool_calls = true # reset each outer iteration
# Inner loop: has_more_tool_calls || !isempty(pending_messages) # Inner loop: has_more_tool_calls || !isempty(pending_messages)
@@ -139,7 +139,7 @@ TextDeltaEvent(partial=AssistantMessage with ToolCall for "read")
TextDeltaEvent(...) -- streaming continues TextDeltaEvent(...) -- streaming continues
ToolCallEvent -- tool call detected: read(file="text.txt") toolcall_start/toolcall_delta/toolcall_end -- tool call detected: read(file="text.txt") (agent_loop.jl:405)
DoneEvent(reason="tool_calls", ...) DoneEvent(reason="tool_calls", ...)
-> final_message = AssistantMessage(role="assistant", content=[ToolCall(...)]) -> final_message = AssistantMessage(role="assistant", content=[ToolCall(...)])
@@ -161,7 +161,7 @@ tool_calls = filter(c -> c isa ToolCall, message.content)
# tool_calls = [ToolCall(type="tool_call", id="call_1", name="read", arguments={file="text.txt"}, ...)] # tool_calls = [ToolCall(type="tool_call", id="call_1", name="read", arguments={file="text.txt"}, ...)]
tool_results = [] tool_results = []
has_more_tool_calls = true has_more_tool_calls = false # set to true only if tool calls execute and don't terminate (agent_loop.jl:225)
if !isempty(tool_calls) if !isempty(tool_calls)
executed_tool_batch = executeToolCalls( executed_tool_batch = executeToolCalls(
@@ -178,8 +178,9 @@ if !isempty(tool_calls)
Since there's only one tool call and no sequential mode forced, it uses `executeToolCallsParallel()` (or sequential -- both paths converge for a single tool call). Since there's only one tool call and no sequential mode forced, it uses `executeToolCallsParallel()` (or sequential -- both paths converge for a single tool call).
```julia ```julia
executeToolCalls(context, assistant_message, tool_calls, config, signal, emit) executeToolCalls(context, assistant_message, config, signal, emit)
-> tool = findfirst(t -> t.name == "read", context.tools) -> tool_calls extracted from assistant_message.content (agent_loop.jl:483-486)
-> tool = findfirst(t -> t.name == "read", context.tools)
-> preparation = prepareToolCall(...) -> preparation = prepareToolCall(...)
-> validated_args = {file="text.txt"} -> validated_args = {file="text.txt"}
-> return PreparedToolCall("prepared", tool_call, tool, validated_args) -> return PreparedToolCall("prepared", tool_call, tool, validated_args)
@@ -291,8 +292,8 @@ Events emitted at end:
| # | Event | Source | | # | Event | Source |
|---|-------|--------| |---|-------|--------|
| 1 | `AgentStartEvent` | runLoop() | | 1 | `AgentStartEvent` | runAgentLoop() |
| 2 | `TurnStartEvent` | runLoop() | | 2 | `TurnStartEvent` | runAgentLoop() |
| 3 | `MessageStartEvent(UserMessage)` | runAgentLoop() | | 3 | `MessageStartEvent(UserMessage)` | runAgentLoop() |
| 4 | `MessageEndEvent(UserMessage)` | runAgentLoop() | | 4 | `MessageEndEvent(UserMessage)` | runAgentLoop() |
| 5 | `MessageStartEvent(AssistantMessage)` | streamAssistantResponse() | | 5 | `MessageStartEvent(AssistantMessage)` | streamAssistantResponse() |
@@ -302,11 +303,12 @@ Events emitted at end:
| 9 | `ToolExecutionEndEvent` | executeToolCalls() | | 9 | `ToolExecutionEndEvent` | executeToolCalls() |
| 10 | `MessageStartEvent(ToolResultMessage)` | emitToolResultMessage() | | 10 | `MessageStartEvent(ToolResultMessage)` | emitToolResultMessage() |
| 11 | `MessageEndEvent(ToolResultMessage)` | emitToolResultMessage() | | 11 | `MessageEndEvent(ToolResultMessage)` | emitToolResultMessage() |
| 12 | `MessageStartEvent(AssistantMessage)` | streamAssistantResponse() (2nd call) | | 12 | `TurnEndEvent(AssistantMessage, [tool_results])` | runLoop() |
| 13 | `MessageUpdateEvent(AssistantMessage)` | streamAssistantResponse() (text streaming) | | 13 | `MessageStartEvent(AssistantMessage)` | streamAssistantResponse() (2nd call) |
| 14 | `MessageEndEvent(AssistantMessage)` | streamAssistantResponse() | | 14 | `MessageUpdateEvent(AssistantMessage)` | streamAssistantResponse() (text streaming) |
| 15 | `TurnEndEvent(AssistantResponse, [])` | runLoop() | | 15 | `MessageEndEvent(AssistantMessage)` | streamAssistantResponse() |
| 16 | `AgentEndEvent([all messages])` | runLoop() | | 16 | `TurnEndEvent(AssistantResponse, [])` | runLoop() |
| 17 | `AgentEndEvent([all messages])` | runLoop() |
--- ---
@@ -380,7 +382,9 @@ executeToolCallsParallel(...)
Events for parallel execution: Events for parallel execution:
``` ```
ToolExecutionStartEvent(call_1, "read", ...) ToolExecutionStartEvent(call_1, "read", ...)
ToolExecutionEndEvent(call_1, "read", ...)
ToolExecutionStartEvent(call_2, "write", ...) ToolExecutionStartEvent(call_2, "write", ...)
ToolExecutionEndEvent(call_2, "write", ...)
MessageStartEvent(ToolResultMessage[read result]) MessageStartEvent(ToolResultMessage[read result])
MessageEndEvent(ToolResultMessage[read result]) MessageEndEvent(ToolResultMessage[read result])
MessageStartEvent(ToolResultMessage[write result]) MessageStartEvent(ToolResultMessage[write result])
@@ -401,9 +405,11 @@ for tool_call in tool_calls:
Events for sequential execution: Events for sequential execution:
``` ```
ToolExecutionStartEvent(call_1, "read", ...) ToolExecutionStartEvent(call_1, "read", ...)
ToolExecutionEndEvent(call_1, "read", ...)
MessageStartEvent(ToolResultMessage[read result]) MessageStartEvent(ToolResultMessage[read result])
MessageEndEvent(ToolResultMessage[read result]) MessageEndEvent(ToolResultMessage[read result])
ToolExecutionStartEvent(call_2, "write", ...) ToolExecutionStartEvent(call_2, "write", ...)
ToolExecutionEndEvent(call_2, "write", ...)
MessageStartEvent(ToolResultMessage[write result]) MessageStartEvent(ToolResultMessage[write result])
MessageEndEvent(ToolResultMessage[write result]) MessageEndEvent(ToolResultMessage[write result])
``` ```
@@ -479,24 +485,26 @@ emit(AgentEndEvent(new_messages))
| # | Event | Source | | # | Event | Source |
|---|-------|--------| |---|-------|--------|
| 1 | `AgentStartEvent` | runLoop() | | 1 | `AgentStartEvent` | runAgentLoop() |
| 2 | `TurnStartEvent` | runLoop() | | 2 | `TurnStartEvent` | runAgentLoop() |
| 3 | `MessageStartEvent(UserMessage)` | runAgentLoop() | | 3 | `MessageStartEvent(UserMessage)` | runAgentLoop() |
| 4 | `MessageEndEvent(UserMessage)` | runAgentLoop() | | 4 | `MessageEndEvent(UserMessage)` | runAgentLoop() |
| 5 | `MessageStartEvent(AssistantMessage)` | streamAssistantResponse() (1st LLM call) | | 5 | `MessageStartEvent(AssistantMessage)` | streamAssistantResponse() (1st LLM call) |
| 6 | `MessageEndEvent(AssistantMessage)` | streamAssistantResponse() | | 6 | `MessageEndEvent(AssistantMessage)` | streamAssistantResponse() |
| 7 | `ToolExecutionStartEvent(call_1, "read")` | executeToolCallsParallel() | | 7 | `ToolExecutionStartEvent(call_1, "read")` | executeToolCallsParallel() |
| 8 | `ToolExecutionStartEvent(call_2, "write")` | executeToolCallsParallel() | | 8 | `ToolExecutionEndEvent(call_1, "read")` | executeToolCallsParallel() |
| 9 | `MessageStartEvent(ToolResultMessage[read])` | emitToolResultMessage() | | 9 | `ToolExecutionStartEvent(call_2, "write")` | executeToolCallsParallel() |
| 10 | `MessageEndEvent(ToolResultMessage[read])` | emitToolResultMessage() | | 10 | `ToolExecutionEndEvent(call_2, "write")` | executeToolCallsParallel() |
| 11 | `MessageStartEvent(ToolResultMessage[write])` | emitToolResultMessage() | | 11 | `MessageStartEvent(ToolResultMessage[read])` | emitToolResultMessage() |
| 12 | `MessageEndEvent(ToolResultMessage[write])` | emitToolResultMessage() | | 12 | `MessageEndEvent(ToolResultMessage[read])` | emitToolResultMessage() |
| 13 | `TurnEndEvent(AssistantToolCalls, [read_result, write_result])` | runLoop() | | 13 | `MessageStartEvent(ToolResultMessage[write])` | emitToolResultMessage() |
| 14 | `MessageStartEvent(AssistantMessage)` | streamAssistantResponse() (2nd LLM call) | | 14 | `MessageEndEvent(ToolResultMessage[write])` | emitToolResultMessage() |
| 15 | `MessageUpdateEvent(AssistantMessage)` | streamAssistantResponse() (text streaming) | | 15 | `TurnEndEvent(AssistantToolCalls, [read_result, write_result])` | runLoop() |
| 16 | `MessageEndEvent(AssistantMessage)` | streamAssistantResponse() | | 16 | `MessageStartEvent(AssistantMessage)` | streamAssistantResponse() (2nd LLM call) |
| 17 | `TurnEndEvent(AssistantResponse, [])` | runLoop() | | 17 | `MessageUpdateEvent(AssistantMessage)` | streamAssistantResponse() (text streaming) |
| 18 | `AgentEndEvent([all messages])` | runLoop() | | 18 | `MessageEndEvent(AssistantMessage)` | streamAssistantResponse() |
| 19 | `TurnEndEvent(AssistantResponse, [])` | runLoop() |
| 20 | `AgentEndEvent([all messages])` | runLoop() |
--- ---