This commit is contained in:
2026-08-21 22:39:51 +07:00
parent d2592ab6d6
commit 5f284883b3
5 changed files with 15 additions and 13 deletions
+4 -4
View File
@@ -10,7 +10,7 @@ Julia framework for building agents with tool use and MCP (Model Context Protoco
```julia ```julia
agent = YiemAgent.yiemAgent(llmCall; mcpServer=mcpServer, eventSink=yourSink) agent = YiemAgent.yiemAgent(llmCall; mcpServer=mcpServer, eventSink=yourSink)
``` ```
4. Call `runAgent(agent, message)` then `takeResponse(agent)` 4. Call `promptAgent(agent, message)` then `takeResponse(agent)`
## Architecture ## Architecture
@@ -20,7 +20,7 @@ src/
├── type.jl # Core types (messages, tools, agent state) ├── type.jl # Core types (messages, tools, agent state)
├── utils.jl # Message formatting, context preparation, validation ├── utils.jl # Message formatting, context preparation, validation
├── agentCore.jl # Agent loop, tool execution pipeline ├── agentCore.jl # Agent loop, tool execution pipeline
├── api.jl # Public API (runAgent, takeResponse, followUp, stopAgent) ├── api.jl # Public API (promptAgent, takeResponse, followUp, stopAgent)
└── toolRegistry.jl # Tool store, MCP discovery, listTools registration └── toolRegistry.jl # Tool store, MCP discovery, listTools registration
``` ```
@@ -114,7 +114,7 @@ Tools are discovered dynamically via MCP server:
| Function | Description | | Function | Description |
|----------|-------------| |----------|-------------|
| `runAgent(agent, msg)` | Send a message to the agent's input channel | | `promptAgent(agent, msg)` | Send a message to the agent's input channel |
| `takeResponse(agent)` | Block and take the agent's response from output channel | | `takeResponse(agent)` | Block and take the agent's response from output channel |
| `followUp(agent, msg)` | Send a follow-up message while agent is still processing | | `followUp(agent, msg)` | Send a follow-up message while agent is still processing |
| `stopAgent(agent)` | Gracefully stop the agent and close channels | | `stopAgent(agent)` | Gracefully stop the agent and close channels |
@@ -122,7 +122,7 @@ Tools are discovered dynamically via MCP server:
## Agent Lifecycle ## Agent Lifecycle
1. `yiemAgent()` spawns a background task (`_agentLoop`) listening on `inputChannel` and `followUpChannel` 1. `yiemAgent()` spawns a background task (`_agentLoop`) listening on `inputChannel` and `followUpChannel`
2. User messages enter via `runAgent()` or `followUp()` 2. User messages enter via `promptAgent()` or `followUp()`
3. `_processMessage()` handles LLM calls, tool execution, and conversation history 3. `_processMessage()` handles LLM calls, tool execution, and conversation history
4. Tool execution follows three phases: `prepareToolCall` → `executePreparedToolCall` → `finalizeExecutedToolCall` 4. Tool execution follows three phases: `prepareToolCall` → `executePreparedToolCall` → `finalizeExecutedToolCall`
5. `beforeToolCall`/`afterToolCall` hooks allow pre/post-processing of tool calls 5. `beforeToolCall`/`afterToolCall` hooks allow pre/post-processing of tool calls
+3 -3
View File
@@ -126,7 +126,7 @@ result = getWeather_tool.execute("call-1", Dict("city" => "Tokyo"), sig, op)
**Via agent loop (production):** **Via agent loop (production):**
``` ```
user message → runAgent(agent, Dict("role"=>"user", "content"=>...)) user message → promptAgent(agent, Dict("role"=>"user", "content"=>...))
→ _agentLoop detects message → @spawn _processMessage(agent) → _agentLoop detects message → @spawn _processMessage(agent)
→ prepareContext → formatMsgForLLM → llmCall → prepareContext → formatMsgForLLM → llmCall
→ LLM returns tool_calls → LLM returns tool_calls
@@ -346,7 +346,7 @@ The `_agentLoop()` function runs as a background `@spawn` task, created when `yi
``` ```
yiemAgent struct contains: yiemAgent struct contains:
- inputChannel (Channel, capacity 16) ← user sends messages here via runAgent() - inputChannel (Channel, capacity 16) ← user sends messages here via promptAgent()
- followUpChannel (Channel, capacity 32) ← user sends follow-ups here via followUp() - followUpChannel (Channel, capacity 32) ← user sends follow-ups here via followUp()
- outputChannel (Channel, capacity 16) ← agent sends responses here via takeResponse() - outputChannel (Channel, capacity 16) ← agent sends responses here via takeResponse()
``` ```
@@ -1243,7 +1243,7 @@ Each `toolStore` gets its own `listTool` instance bound to that store via `listT
``` ```
USER SENDS MESSAGE USER SENDS MESSAGE
└─> runAgent(agent, "What's the weather in Tokyo?") └─> promptAgent(agent, "What's the weather in Tokyo?")
└─> put!(agent.inputChannel, Dict("role" => "user", "content" => [...])) └─> put!(agent.inputChannel, Dict("role" => "user", "content" => [...]))
+2
View File
@@ -21,6 +21,8 @@ module YiemAgent
include("api.jl") include("api.jl")
using .api using .api
export promptAgent, takeResponse, followUp, stopAgent
# ---------------------------------------------- 100 --------------------------------------------- # # ---------------------------------------------- 100 --------------------------------------------- #
+5 -5
View File
@@ -1,6 +1,6 @@
module api module api
export prompt export promptAgent, takeResponse, followUp, stopAgent
using JSON, DataStructures, Dates, UUIDs, HTTP, Random, PrettyPrinting, Serialization, using JSON, DataStructures, Dates, UUIDs, HTTP, Random, PrettyPrinting, Serialization,
DataFrames DataFrames
@@ -29,11 +29,11 @@ The agent processes messages from `inputChannel` in the background task.
# Examples # Examples
```jldoctest ```jldoctest
julia> runAgent(agent, Dict("role" => "user", "content" => "Hello!")) julia> promptAgent(agent, Dict("role" => "user", "content" => "Hello!"))
yiemAgent(...) yiemAgent(...)
``` ```
""" """
function runAgent(agent::yiemAgent, msg::AbstractDict{String, Any}) function promptAgent(agent::yiemAgent, msg::AbstractDict{String, Any})
put!(agent.inputChannel, msg) put!(agent.inputChannel, msg)
return agent return agent
end end
@@ -50,7 +50,7 @@ Blocks until the agent sends a response.
- An `assistantMessage` instance representing the agent's response - An `assistantMessage` instance representing the agent's response
# Notes # Notes
- Use `runAgent(agent, msg)` to send a message before calling this function. - Use `promptAgent(agent, msg)` to send a message before calling this function.
# Examples # Examples
```jldoctest ```jldoctest
@@ -76,7 +76,7 @@ and before any tool call results are sent.
- The same `agent` instance for chaining - The same `agent` instance for chaining
# Notes # Notes
- Use `runAgent(agent, msg)` for the primary message and `followUp(agent, msg)` for additional - Use `promptAgent(agent, msg)` for the primary message and `followUp(agent, msg)` for additional
messages while the agent is processing. messages while the agent is processing.
- Follow-up messages are buffered in a separate channel (capacity 32 by default). - Follow-up messages are buffered in a separate channel (capacity 32 by default).
+1 -1
View File
@@ -23,7 +23,7 @@
preparedToolCall, immediateOutcome, executedOutcome, finalizedOutcome, preparedToolCall, immediateOutcome, executedOutcome, finalizedOutcome,
agentToolCallBatch, agentToolCallBatch,
# Functions (defined elsewhere) # Functions (defined elsewhere)
runAgent, takeResponse, followUp, stopAgent promptAgent, takeResponse, followUp, stopAgent
using Dates, UUIDs, DataStructures, JSON, NATS, Base.Threads using Dates, UUIDs, DataStructures, JSON, NATS, Base.Threads