update
This commit is contained in:
@@ -27,11 +27,16 @@ agentLoopContinue()
|
||||
└─ Returns: EventStream
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Internal Flow │
|
||||
│ Data Flow with Type Transformations │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ 1. runAgentLoop() ── Entry point for new conversation │
|
||||
│ Input: prompts::Vector{AgentMessage} │
|
||||
│ context::AgentContext (system_prompt, messages, tools) │
|
||||
│ config::AgentLoopConfig │
|
||||
│ Output: new_messages::Vector{AgentMessage} (appended prompts + turns) │
|
||||
│ │
|
||||
│ - Creates copy of prompts │
|
||||
│ - Appends prompts to context.messages │
|
||||
│ - Emits AgentStartEvent │
|
||||
@@ -43,12 +48,20 @@ agentLoopContinue()
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ 2. runLoop() ── Main event loop │
|
||||
│ Input: current_context::AgentContext │
|
||||
│ new_messages::Vector{AgentMessage} │
|
||||
│ Output: N/A (writes to new_messages and context.messages) │
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ while true: │ │
|
||||
│ │ 1. Get steering/follow-up messages (if any) │ │
|
||||
│ │ 2. Emit messages as UserMessage │ │
|
||||
│ │ 3. streamAssistantResponse() │ │
|
||||
│ │ - Input: context.messages::Vector{AgentMessage} │ │
|
||||
│ │ - Output: message::AssistantMessage │ │
|
||||
│ │ 4. Execute tool calls (sequential or parallel) │ │
|
||||
│ │ - Input: AssistantMessage with ToolCall[] │ │
|
||||
│ │ - Output: tool_results::Vector{ToolResultMessage} │ │
|
||||
│ │ 5. Emit TurnEndEvent │ │
|
||||
│ │ 6. prepare_next_turn (optional) │ │
|
||||
│ │ 7. should_stop_after_turn? (check termination) │ │
|
||||
@@ -59,27 +72,89 @@ agentLoopContinue()
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ 3. streamAssistantResponse() ── LLM interaction │
|
||||
│ - transform_context (optional) │
|
||||
│ - convert_to_llm (transform to Message[]) │
|
||||
│ - Call stream_fn (LLM API) │
|
||||
│ - Stream response deltas │
|
||||
│ - Emit MessageStart/Update/End events │
|
||||
│ Input: context::AgentContext │
|
||||
│ config::AgentLoopConfig │
|
||||
│ Output: message::AssistantMessage │
|
||||
│ │
|
||||
│ Data Transformations: │
|
||||
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Step 1: transform_context (optional) │ │
|
||||
│ │ Input: context.messages::Vector{AgentMessage} │ │
|
||||
│ │ Output: messages::Vector{AgentMessage} (transformed) │ │
|
||||
│ │ │ │
|
||||
│ │ Step 2: convert_to_llm │ │
|
||||
│ │ Input: messages::Vector{AgentMessage} │ │
|
||||
│ │ Output: llm_messages::Vector{Message} │ │
|
||||
│ │ - UserMessage → UserMessage │ │
|
||||
│ │ - AssistantMessage → AssistantMessage │ │
|
||||
│ │ - ToolResultMessage → ToolResultMessage │ │
|
||||
│ │ - BashExecutionMessage → UserMessage │ │
|
||||
│ │ - CompactionSummaryMessage → UserMessage │ │
|
||||
│ │ - BranchSummaryMessage → UserMessage │ │
|
||||
│ │ │ │
|
||||
│ │ Step 3: Call stream_fn │ │
|
||||
│ │ Input: model, llm_context::Context, config │ │
|
||||
│ │ Output: response::Stream (events) │ │
|
||||
│ │ │ │
|
||||
│ │ Step 4: Stream events │ │
|
||||
│ │ Events: start, text_start/delta/end, toolcall_start/delta/end │ │
|
||||
│ │ Final: AssistantMessage (with ToolCall[] in content) │ │
|
||||
│ └────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ 4. executeToolCalls() ── Tool execution │
|
||||
│ Input: assistant_message::AssistantMessage (contains ToolCall[]) │
|
||||
│ current_context::AgentContext │
|
||||
│ Output: ExecutedToolCallBatch (messages::ToolResultMessage[], terminate) │
|
||||
│ │
|
||||
│ For each ToolCall: │
|
||||
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ if EXECUTION_SEQUENTIAL || has_sequential_tool: │ │
|
||||
│ │ executeToolCallsSequential() │ │
|
||||
│ │ else: │ │
|
||||
│ │ executeToolCallsParallel() │ │
|
||||
│ │ prepareToolCall() │ │
|
||||
│ │ Input: tool_call::ToolCall │ │
|
||||
│ │ Output: PreparedToolCall or ImmediateToolCallOutcome │ │
|
||||
│ │ - validates arguments │ │
|
||||
│ │ - runs before_tool_call hook (optional) │ │
|
||||
│ │ - runs prepare_arguments hook (optional) │ │
|
||||
│ │ │ │
|
||||
│ │ executePreparedToolCall() (if prepared) │ │
|
||||
│ │ Input: PreparedToolCall │ │
|
||||
│ │ Output: ExecutedToolCallOutcome │ │
|
||||
│ │ - calls tool.execute() │ │
|
||||
│ │ - returns AgentToolResultMutable │ │
|
||||
│ │ │ │
|
||||
│ │ finalizeExecutedToolCall() │ │
|
||||
│ │ Input: ExecutedToolCallOutcome │ │
|
||||
│ │ Output: FinalizedToolCallOutcome │ │
|
||||
│ │ - runs after_tool_call hook (optional) │ │
|
||||
│ │ - returns ToolCall + AgentToolResultMutable + is_error │ │
|
||||
│ │ │ │
|
||||
│ │ createToolResultMessage() │ │
|
||||
│ │ Input: FinalizedToolCallOutcome │ │
|
||||
│ │ Output: ToolResultMessage │ │
|
||||
│ │ - role: "toolResult" │ │
|
||||
│ │ - tool_call_id, tool_name, content, details │ │
|
||||
│ │ - usage, added_tool_names, is_error, timestamp │ │
|
||||
│ └────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Sequential: executeToolCallsSequential() │ │
|
||||
│ │ - Executes tools one at a time, waits for each │ │
|
||||
│ │ - Returns batch of ToolResultMessage[] │ │
|
||||
│ │ │ │
|
||||
│ │ Parallel: executeToolCallsParallel() │ │
|
||||
│ │ - Creates closures for async execution │ │
|
||||
│ │ - Executes all closures, collects results │ │
|
||||
│ │ - Returns batch of ToolResultMessage[] │ │
|
||||
│ └────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ 5. AgentEndEvent ── Final event with all messages │
|
||||
│ Output: messages::Vector{AgentMessage} │
|
||||
│ Contains: [UserMessage, AssistantMessage, ToolResultMessage, ...] │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -301,17 +376,44 @@ function streamAssistantResponse(
|
||||
)::AssistantMessage
|
||||
```
|
||||
|
||||
**Flow**:
|
||||
1. Get messages from context
|
||||
2. Apply transform_context (optional)
|
||||
3. Convert to LLM messages with convert_to_llm
|
||||
4. Create Context object
|
||||
5. Resolve API key
|
||||
6. Call stream_fn with model, context, and config
|
||||
7. Stream events:
|
||||
- "start" → MessageStartEvent
|
||||
- "text_start", "text_delta", "text_end" → MessageUpdateEvent
|
||||
- "done", "error" → MessageEndEvent
|
||||
**Data Flow**:
|
||||
|
||||
```
|
||||
Input: context.messages::Vector{AgentMessage}
|
||||
↓
|
||||
[transform_context] (optional hook)
|
||||
↓
|
||||
messages::Vector{AgentMessage}
|
||||
↓
|
||||
[convert_to_llm] - Type transformation pipeline
|
||||
↓
|
||||
llm_messages::Vector{Message}
|
||||
│
|
||||
│ AgentMessage → Message mapping:
|
||||
│ • UserMessage → UserMessage (pass-through)
|
||||
│ • AssistantMessage → AssistantMessage (pass-through)
|
||||
│ • ToolResultMessage → ToolResultMessage (pass-through)
|
||||
│ • BashExecutionMessage → UserMessage (text conversion)
|
||||
│ • CompactionSummaryMessage → UserMessage (text wrapped)
|
||||
│ • BranchSummaryMessage → UserMessage (text wrapped)
|
||||
│
|
||||
▼
|
||||
Context(system_prompt, llm_messages, tools)
|
||||
↓
|
||||
stream_fn(model, context, config) - LLM API call
|
||||
↓
|
||||
Stream of AssistantMessageEvent:
|
||||
• StartEvent (partial AssistantMessage)
|
||||
• TextStartEvent/TextDeltaEvent/TextEndEvent
|
||||
• ToolCallStartEvent/ToolCallDeltaEvent/ToolCallEndEvent
|
||||
• DoneEvent (final AssistantMessage with usage, stop_reason)
|
||||
↓
|
||||
Return: AssistantMessage
|
||||
- content::Vector{MessageContent}
|
||||
- usage::Usage
|
||||
- stop_reason::String
|
||||
- Contains ToolCall[] if tool calls requested
|
||||
```
|
||||
|
||||
### executeToolCalls()
|
||||
|
||||
@@ -320,27 +422,56 @@ function executeToolCalls(
|
||||
current_context::AgentContext,
|
||||
assistant_message::AssistantMessage,
|
||||
config::AgentLoopConfig,
|
||||
signal::Union{Nothing, AbortSignal},
|
||||
signal::Union{Nothing, AbortSignal>,
|
||||
emit::AgentEventSink,
|
||||
)::ExecutedToolCallBatch
|
||||
```
|
||||
|
||||
**Logic**:
|
||||
```julia
|
||||
tool_calls = filter(c -> c isa ToolCall, assistant_message.content)
|
||||
**Data Flow**:
|
||||
|
||||
# Check if any tool requires sequential execution
|
||||
has_sequential = any(tc -> begin
|
||||
tool = findfirst(t -> t.name == tc.name, current_context.tools)
|
||||
!isnothing(tool) && tool.execution_mode == EXECUTION_SEQUENTIAL
|
||||
end, tool_calls)
|
||||
|
||||
# Determine execution mode
|
||||
if config.tool_execution == EXECUTION_SEQUENTIAL || has_sequential
|
||||
executeToolCallsSequential(...)
|
||||
else
|
||||
executeToolCallsParallel(...)
|
||||
end
|
||||
```
|
||||
Input: assistant_message::AssistantMessage
|
||||
- content::Vector{MessageContent}
|
||||
└─ Contains ToolCall[] and/or TextContent[]
|
||||
↓
|
||||
filter(c -> c isa ToolCall, assistant_message.content)
|
||||
↓
|
||||
tool_calls::Vector{ToolCall}
|
||||
- type: "tool"
|
||||
- id::String
|
||||
- name::String
|
||||
- arguments::Dict{String, Any}
|
||||
- partial_json::Union{String, Nothing}
|
||||
↓
|
||||
Check execution mode:
|
||||
• config.tool_execution (sequential/parallel)
|
||||
• Any tool.execution_mode == EXECUTION_SEQUENTIAL?
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Sequential Mode (or has_sequential_tool) │
|
||||
│ For each tool_call in tool_calls: │
|
||||
│ prepareToolCall() → PreparedToolCall │
|
||||
│ executePreparedToolCall() → ExecutedToolCallOutcome │
|
||||
│ finalizeExecutedToolCall() → FinalizedToolCallOutcome │
|
||||
│ createToolResultMessage() → ToolResultMessage │
|
||||
│ (wait for completion before next tool) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Parallel Mode │
|
||||
│ For each tool_call in tool_calls: │
|
||||
│ prepareToolCall() → (PreparedToolCall | ImmediateOutcome) │
|
||||
│ If prepared: create closure │
|
||||
│ If immediate: execute and add to finalized_calls │
|
||||
│ │
|
||||
│ For each entry in finalized_calls: │
|
||||
│ If closure: execute closure │
|
||||
│ If finalized: use as-is │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
ExecutedToolCallBatch
|
||||
- messages::Vector{ToolResultMessage}
|
||||
- terminate::Bool (true if all tools have terminate=true)
|
||||
```
|
||||
|
||||
### executeToolCallsSequential()
|
||||
@@ -400,29 +531,77 @@ function prepareToolCall(
|
||||
)::Union{PreparedToolCall, ImmediateToolCallOutcome}
|
||||
```
|
||||
|
||||
**Flow**:
|
||||
1. Find tool by name
|
||||
2. If not found → ImmediateToolCallOutcome (error)
|
||||
3. before_tool_call hook (optional)
|
||||
4. prepareToolCallArguments() (optional)
|
||||
5. validateToolArguments()
|
||||
6. Return PreparedToolCall
|
||||
**Data Flow**:
|
||||
|
||||
```
|
||||
Input: tool_call::ToolCall
|
||||
- id::String
|
||||
- name::String
|
||||
- arguments::Dict{String, Any}
|
||||
↓
|
||||
findfirst(t -> t.name == tool_call.name, current_context.tools)
|
||||
↓
|
||||
If tool is nothing:
|
||||
→ ImmediateToolCallOutcome("immediate", error_result, is_error=true)
|
||||
↓
|
||||
If tool exists:
|
||||
[before_tool_call hook] (optional)
|
||||
Input: BeforeToolCallContext(assistant_message, tool_call, args, context)
|
||||
Output: BeforeToolCallResult (block, reason) or nothing
|
||||
If block=true → ImmediateToolCallOutcome(error)
|
||||
↓
|
||||
prepareToolCallArguments(tool, tool_call)
|
||||
Input: tool_call.arguments::Dict{String, Any}
|
||||
Output: prepared_arguments::Any
|
||||
(Optional: transform arguments before validation)
|
||||
↓
|
||||
validateToolArguments(tool, prepared_tool_call)
|
||||
Input: prepared_tool_call.arguments
|
||||
Output: validated_args::Any
|
||||
(Optional: JSON schema validation)
|
||||
↓
|
||||
Return: PreparedToolCall("prepared", tool_call, tool, validated_args)
|
||||
- kind: "prepared"
|
||||
- tool_call: ToolCall (original)
|
||||
- tool: AgentTool
|
||||
- args: validated arguments
|
||||
```
|
||||
|
||||
### executePreparedToolCall()
|
||||
|
||||
```julia
|
||||
function executePreparedToolCall(
|
||||
prepared::PreparedToolCall,
|
||||
signal::Union{Nothing, AbortSignal},
|
||||
signal::Union{Nothing, AbortSignal>,
|
||||
emit::AgentEventSink,
|
||||
)::ExecutedToolCallOutcome
|
||||
```
|
||||
|
||||
**Flow**:
|
||||
1. Call tool.execute(id, args, signal, on_update)
|
||||
2. Collect update events (if any)
|
||||
3. Wait for all update events
|
||||
4. Return ExecutedToolCallOutcome(result)
|
||||
**Data Flow**:
|
||||
|
||||
```
|
||||
Input: prepared::PreparedToolCall
|
||||
- tool_call::ToolCall
|
||||
- tool::AgentTool
|
||||
- args::Any (validated)
|
||||
↓
|
||||
tool.execute(tool_call.id, args, signal, on_update)
|
||||
Input: tool_call_id::String
|
||||
args::Any
|
||||
signal::Union{Any, Nothing}
|
||||
on_update::Function (partial_result → void)
|
||||
Output: AgentToolResultMutable
|
||||
- content::Vector{MessageContent}
|
||||
- details::Any
|
||||
- usage::Union{Usage, Nothing}
|
||||
- added_tool_names::Union{Vector{String}, Nothing}
|
||||
- terminate::Union{Bool, Nothing}
|
||||
↓
|
||||
Collect update events from on_update callbacks
|
||||
↓
|
||||
Return: ExecutedToolCallOutcome(result, is_error=false)
|
||||
- result::AgentToolResultMutable
|
||||
```
|
||||
|
||||
### finalizeExecutedToolCall()
|
||||
|
||||
@@ -433,13 +612,43 @@ function finalizeExecutedToolCall(
|
||||
prepared::PreparedToolCall,
|
||||
executed::ExecutedToolCallOutcome,
|
||||
config::AgentLoopConfig,
|
||||
signal::Union{Nothing, AbortSignal},
|
||||
signal::Union{Nothing, AbortSignal>,
|
||||
)::FinalizedToolCallOutcome
|
||||
```
|
||||
|
||||
**Flow**:
|
||||
1. after_tool_call hook (optional)
|
||||
2. Return FinalizedToolCallOutcome
|
||||
**Data Flow**:
|
||||
|
||||
```
|
||||
Input: executed::ExecutedToolCallOutcome
|
||||
- result::AgentToolResultMutable
|
||||
- is_error::Bool
|
||||
↓
|
||||
[after_tool_call hook] (optional)
|
||||
Input: AfterToolCallContext(
|
||||
assistant_message,
|
||||
tool_call,
|
||||
args,
|
||||
result,
|
||||
is_error,
|
||||
context
|
||||
)
|
||||
Output: AfterToolCallResult (optional patches)
|
||||
- content::Union{Vector{MessageContent}, Nothing}
|
||||
- details::Union{Any, Nothing}
|
||||
- is_error::Union{Bool, Nothing}
|
||||
- usage::Union{Usage, Nothing}
|
||||
- terminate::Union{Bool, Nothing}
|
||||
↓
|
||||
Apply patches to result (if any)
|
||||
result.content = result.content ∪ patches.content
|
||||
result.details = result.details ∪ patches.details
|
||||
is_error = is_error ∪ patches.is_error
|
||||
↓
|
||||
Return: FinalizedToolCallOutcome
|
||||
- tool_call::ToolCall (original)
|
||||
- result::AgentToolResultMutable (final)
|
||||
- is_error::Bool
|
||||
```
|
||||
|
||||
### createToolResultMessage()
|
||||
|
||||
@@ -449,19 +658,39 @@ function createToolResultMessage(
|
||||
)::ToolResultMessage
|
||||
```
|
||||
|
||||
**Creates**:
|
||||
```julia
|
||||
ToolResultMessage(
|
||||
"toolResult",
|
||||
finalized.tool_call.id,
|
||||
finalized.tool_call.name,
|
||||
finalized.result.content,
|
||||
finalized.result.details,
|
||||
finalized.result.usage,
|
||||
finalized.result.added_tool_names,
|
||||
finalized.is_error,
|
||||
timestamp,
|
||||
)
|
||||
**Data Flow**:
|
||||
|
||||
```
|
||||
Input: finalized::FinalizedToolCallOutcome
|
||||
- tool_call::ToolCall
|
||||
- result::AgentToolResultMutable
|
||||
- content::Vector{MessageContent}
|
||||
- details::Any
|
||||
- usage::Union{Usage, Nothing}
|
||||
- added_tool_names::Union{Vector{String}, Nothing}
|
||||
- is_error::Bool
|
||||
↓
|
||||
Build ToolResultMessage:
|
||||
• role: "toolResult"
|
||||
• tool_call_id: tool_call.id
|
||||
• tool_name: tool_call.name
|
||||
• content: result.content
|
||||
• details: result.details
|
||||
• usage: result.usage
|
||||
• added_tool_names: result.added_tool_names
|
||||
• is_error: is_error
|
||||
• timestamp: Int64(Dates.now(Dates.UTC).datetime)
|
||||
↓
|
||||
Output: ToolResultMessage
|
||||
- role::String ("toolResult")
|
||||
- tool_call_id::String
|
||||
- tool_name::String
|
||||
- content::Vector{MessageContent}
|
||||
- details::Any
|
||||
- usage::Union{Usage, Nothing}
|
||||
- added_tool_names::Union{Vector{String}, Nothing}
|
||||
- is_error::Bool
|
||||
- timestamp::Timestamp (Int64)
|
||||
```
|
||||
|
||||
## Execution Modes
|
||||
@@ -650,35 +879,70 @@ AgentStartEvent
|
||||
### 1. Message Transformation Pipeline
|
||||
|
||||
```
|
||||
AgentMessage[] (internal)
|
||||
Vector{AgentMessage} (internal conversation history)
|
||||
│
|
||||
│ transform_context()
|
||||
▼
|
||||
AgentMessage[] (transformed)
|
||||
├─ transform_context() (optional hook)
|
||||
│ Input: Vector{AgentMessage}
|
||||
│ Output: Vector{AgentMessage} (transformed)
|
||||
│
|
||||
│ convert_to_llm()
|
||||
▼
|
||||
Message[] (LLM API)
|
||||
└─ convert_to_llm()
|
||||
│
|
||||
│ Type mapping (single dispatch):
|
||||
│ • UserMessage → UserMessage (pass-through)
|
||||
│ • AssistantMessage → AssistantMessage (pass-through)
|
||||
│ • ToolResultMessage → ToolResultMessage (pass-through)
|
||||
│ • BashExecutionMessage → UserMessage (text conversion)
|
||||
│ • CompactionSummaryMessage → UserMessage (text wrapped)
|
||||
│ • BranchSummaryMessage → UserMessage (text wrapped)
|
||||
│
|
||||
▼
|
||||
Vector{Message} (for LLM API)
|
||||
```
|
||||
|
||||
### 2. Tool Call Lifecycle
|
||||
### 2. Tool Call Lifecycle (with Data Transformations)
|
||||
|
||||
```
|
||||
ToolCall (in assistant message)
|
||||
ToolCall (in AssistantMessage.content)
|
||||
│
|
||||
├─ before_tool_call (hook)
|
||||
├─ before_tool_call hook (optional)
|
||||
│ Input: BeforeToolCallContext(
|
||||
│ assistant_message::AssistantMessage,
|
||||
│ tool_call::ToolCall,
|
||||
│ args::Dict{String, Any},
|
||||
│ context::AgentContext
|
||||
│ )
|
||||
│ Output: BeforeToolCallResult (block, reason) or nothing
|
||||
│
|
||||
├─ prepareToolCall()
|
||||
│ ├─ validate arguments
|
||||
│ └─ prepare arguments (optional)
|
||||
│ Input: tool_call::ToolCall
|
||||
│ Output: Union{PreparedToolCall, ImmediateToolCallOutcome}
|
||||
│ • PreparedToolCall (kind, tool_call, tool, args)
|
||||
│ • ImmediateToolCallOutcome (immediate, result, is_error)
|
||||
│
|
||||
├─ execute()
|
||||
│ ├─ Immediate: return result
|
||||
│ └─ Prepared: async execution
|
||||
├─ executePreparedToolCall() (if prepared)
|
||||
│ Input: PreparedToolCall
|
||||
│ Output: ExecutedToolCallOutcome
|
||||
│ tool.execute() returns AgentToolResultMutable
|
||||
│ • content::Vector{MessageContent}
|
||||
│ • details::Any
|
||||
│ • usage::Union{Usage, Nothing}
|
||||
│ • terminate::Union{Bool, Nothing}
|
||||
│
|
||||
├─ after_tool_call (hook)
|
||||
├─ finalizeExecutedToolCall()
|
||||
│ Input: ExecutedToolCallOutcome
|
||||
│ Output: FinalizedToolCallOutcome
|
||||
│ • tool_call::ToolCall
|
||||
│ • result::AgentToolResultMutable
|
||||
│ • is_error::Bool
|
||||
│
|
||||
└─ createToolResultMessage()
|
||||
Input: FinalizedToolCallOutcome
|
||||
Output: ToolResultMessage
|
||||
• role: "toolResult"
|
||||
• tool_call_id, tool_name
|
||||
• content::Vector{MessageContent}
|
||||
• details, usage, added_tool_names
|
||||
• is_error, timestamp
|
||||
```
|
||||
|
||||
### 3. Turn Termination
|
||||
|
||||
Reference in New Issue
Block a user