From 4ac5b97d5334e5f2d4387caaa31e9c8950078cfc Mon Sep 17 00:00:00 2001 From: narawat Date: Thu, 3 Sep 2026 09:49:52 +0700 Subject: [PATCH] update --- src/agentCore.jl | 38 +++++++++++++++++++++----------------- src/utils.jl | 12 ++++-------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/agentCore.jl b/src/agentCore.jl index d49bb32..9c196fc 100644 --- a/src/agentCore.jl +++ b/src/agentCore.jl @@ -19,6 +19,7 @@ mutable struct yiemAgent <: agent # High-level agent wrapper # user sends prompt message to agent. if agent is idle, it process user message right away. # if agent is running, it process user message after the current tool call finished. + # Expect each message in OpenAI chat format inputChannel::Channel # Buffers messages the user sends while the agent is busy. Processed after all inputChannel @@ -422,7 +423,7 @@ function _processMessage( response = JSON.Object{String, Any}("finish_reason" => "tool_calls", "index" => 0, "message" => JSON.Object{String, Any}("role" => "assistant", "content" => "", "reasoning_content" => "Here's a thinking process:\n\n1. **Identify User Request**: The user is asking for the weather in Bangkok.\n2. **Locate Relevant Tool**: I have a `getWeather` function available.\n3. **Check Function Parameters**:\n - `city` (required): City and country, e.g., 'San Francisco, CA' or 'Tokyo, Japan'\n - `units` (optional, default \"celsius\"): Temperature scale (\"celsius\" or \"fahrenheit\")\n4. **Prepare Parameters**:\n - `city`: \"Bangkok, Thailand\" (adding country for clarity, though just \"Bangkok\" might work, following the example format is safer)\n - `units`: Not specified, so I'll use the default (\"celsius\")\n5. **Execute Tool Call**: Call `getWeather` with `city: \"Bangkok, Thailand\"`\n6. **Anticipate Response**: The function will return current weather and forecast data for Bangkok. I'll then format it nicely for the user.\n - *Self-Correction/Verification during thought*: The prompt says \"city: City and country, e.g., 'San Francisco, CA' or 'Tokyo, Japan'\". I'll use \"Bangkok, Thailand\". The `units` parameter is optional, so I'll omit it to use the default.\n - Proceed with tool call.✅\n", "tool_calls" => Any[JSON.Object{String, Any}("type" => "function", "function" => JSON.Object{String, Any}("name" => "getWeather", "arguments" => "{\"city\":\"Bangkok, Thailand\"}"), "id" => "6fOilR5QPcdppbAAHluhkRyUDu3oWMAL")])) """ response = llmCall(formattedMessages) - eventSink("LLM response " * string(response); publish=false, log=true) + # eventSink("LLM response " * string(response); publish=false, log=true) eventSink("_processMessage 11 _state.messages length $(length(agentMsgHistory))"; publish=false, log=true) # Extract tool calls from LLM response content blocks @@ -453,7 +454,7 @@ function _processMessage( # save toolResults to messages for toolResult in toolResultBatch.messages - eventSink("toolResult " * string(toolResult); publish=false, log=true) + # eventSink("toolResult " * string(toolResult); publish=false, log=true) push!(agentMsgHistory, toolResult) end eventSink("_processMessage 14 _state.messages length $(length(agentMsgHistory))"; publish=false, log=true) @@ -538,7 +539,7 @@ agentToolResult([textContent("text", "Tool not found")], Dict{Any,Any}()) ``` """ function createErrorToolResult(msg::String)::agentToolResult - return agentToolResult([textContent("text", msg)], dict{any,any}()) + return agentToolResult([textContent("text", msg)], Dict{Any,Any}()) end """ @@ -830,10 +831,10 @@ stopping the agent when other tools in the batch did not intend to terminate. julia> shouldTerminate(finalizedOutcome[]) false -julia> shouldTerminate([finalizedOutcome(tc, agentToolResult([], dict{any,any}(), dict{any,any}(), false), false) for _ in 1:2]) +julia> shouldTerminate([finalizedOutcome(tc, agentToolResult([], Dict{Any,Any}(), Dict{Any,Any}(), false), false) for _ in 1:2]) false -julia> shouldTerminate([finalizedOutcome(tc, agentToolResult([], dict{any,any}(), dict{any,any}(), true), false) for _ in 1:2]) +julia> shouldTerminate([finalizedOutcome(tc, agentToolResult([], Dict{Any,Any}(), Dict{Any,Any}(), true), false) for _ in 1:2]) true ``` """ @@ -972,7 +973,8 @@ function prepareToolCall( before = config.beforeToolCall( beforeToolCallContext(assistantMsg, toolCall, validatedArgs, context), - signal + signal, + eventSink ) eventSink("prepareToolCall 7"; publish=false, log=true) if signal.aborted @@ -1034,7 +1036,7 @@ emitted after the result has already been captured. ```julia # Successful execution executePreparedToolCall(prep, nothing, emit) -# => executedOutcome(agentToolResult([textContent("text", "Found 3 wines")], dict{any,any}(), dict{any,any}()), false) +# => executedOutcome(agentToolResult([textContent("text", "Found 3 wines")], Dict{Any,Any}(), Dict{Any,Any}()), false) # Execution error executePreparedToolCall(prep, nothing, emit) @@ -1049,8 +1051,11 @@ function executePreparedToolCall( )::executedOutcome eventSink("executePreparedToolCall 1"; publish=false, log=true) - try #WORKING pass sessionId from yiemAgent to tool call + try + result = prep.tool.execute(prep.toolCall.id, prep.args, signal, eventSink) + + eventSink("executePreparedToolCall 2"; publish=false, log=true) eventSink("tool execute raw result: " * sprint(show, result); publish=false, log=true) eventSink("executePreparedToolCall 3"; publish=false, log=true) @@ -1065,6 +1070,7 @@ function executePreparedToolCall( return executedOutcome(createErrorToolResult(sprint(showerror, e)), true) end + end @@ -1136,20 +1142,18 @@ function finalizeExecutedToolCall( eventSink("finalizeExecutedToolCall 1"; publish=false, log=true) result = executed.result isError = executed.isError - eventSink("finalizeExecutedToolCall 2"; publish=false, log=true) + eventSink("finalizeExecutedToolCall result before afterToolCall\n$result"; publish=false, log=true) if config.afterToolCall !== nothing try after = config.afterToolCall( afterToolCallContext(assistantMsg, prep.toolCall, prep.args, result, isError, context), - signal + signal, + eventSink ) eventSink("finalizeExecutedToolCall 3"; publish=false, log=true) if after !== nothing - result = merge(result, dict(:content=>get(after,:content,result.content), - :details=>get(after,:details,result.details), - :usage=>get(after,:usage,result.usage), - :terminate=>get(after,:terminate,result.terminate))) - isError = get(after, :isError, isError) + result = after + isError = false end catch e bt = catch_backtrace() @@ -1252,8 +1256,8 @@ function executeToolCallsSequential( eventSink("executeToolCallsSequential 3-2"; publish=false, log=true) end eventSink("executeToolCallsSequential 4"; publish=false, log=true) - eventSink("finalized $(finalized.toolCall.id), $(finalized.toolCall.name), - $(finalized.result), $(finalized.isError)"; publish=false, log=true) + # eventSink("finalized $(finalized.toolCall.id), $(finalized.toolCall.name), + # $(finalized.result), $(finalized.isError)"; publish=false, log=true) push!(messages, createToolResultMessage(finalized)) push!(finalizedCalls, finalized) eventSink("executeToolCallsSequential 5"; publish=false, log=true) diff --git a/src/utils.jl b/src/utils.jl index 73349e0..815f3a0 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -275,14 +275,10 @@ function beforeToolCall(context::beforeToolCallContext, signal::abortSignal) end ``` """ -function beforeToolCall(context::beforeToolCallContext, signal::abortSignal +function beforeToolCall(context::beforeToolCallContext, signal::abortSignal, eventSink )::beforeToolCallResult - # final context check - - # seek user approval via UI - - # other check + eventSink("beforeToolCall: $(context.toolCall.name) args=$(context.args)") return beforeToolCallResult(false, "N/A") end @@ -311,10 +307,10 @@ Common use cases: terminate flag can all be overridden). """ #WORKING arrange result from searchWine tool -function afterToolCall(context::afterToolCallContext, signal::abortSignal +function afterToolCall(context::afterToolCallContext, signal::abortSignal, eventSink )::Union{agentToolResult, Nothing} - # modify context.result if needed and return agentToolResult + eventSink("afterToolCall: $(context.toolCall.name) result=$(context.result) error=$(context.isError)") return nothing end