Files
YiemAgent/docs/1-requirements.md
2026-09-11 08:28:49 +07:00

8.8 KiB

YiemAgent: Agile Agent Framework

1. Business Context & Success Metrics

Business Goal

YiemAgent is a Julia-based AI agent framework that enables building chatbot assistants with tool-calling capabilities, model-agnostic LLM integration, and runtime tool discovery via MCP (Model Context Protocol). It provides an asynchronous agent loop with channel-based message passing, supporting both single-turn and multi-turn conversations with automatic tool call resolution.

User Stories

  • US-001: As a developer, I want to create an AI agent with a simple constructor so that I can quickly prototype chatbot functionality in Julia
  • US-002: As a developer, I want the agent to discover tools automatically from an MCP server so that I don't need to manually register tool APIs
  • US-003: As a developer, I want the agent to handle tool calls automatically in a loop so that the LLM can use tools without external orchestration
  • US-004: As a developer, I want to intercept tool calls with before/after hooks so that I can add user approval, logging, or result sanitization
  • US-005: As a developer, I want the framework to support multiple LLM models and providers through a pluggable llmCall interface so that I can swap models without changing agent logic

KPIs & Targets

  • KPI-001: Agent loop processes messages with <500ms overhead for sequential tool calls (validates US-003)
  • KPI-002: MCP tool discovery completes within 2 seconds for 50+ tools (validates US-002)
  • KPI-003: 100% of message types have OpenAI format conversion (validates US-001)

2. Technical Boundaries

In Scope

  • Julia module implementing an AI agent with asynchronous message processing
  • Channel-based input (user→agent), follow-up (async queue), and output (agent→user) interfaces
  • LLM model abstraction with tool call extraction from multiple response formats (OpenAI content blocks, LMStudio/vLLM format)
  • Tool registry with MCP server integration (tools/list, tools/call via JSON-RPC 2.0)
  • Agent loop with before/after tool call hooks for lifecycle management
  • Message type system with OpenAI format conversion utilities
  • Abort signal and termination flag support via tool implementations

Out of Scope

  • GUI/CLI interface (exposed via channels only; UI layer is external)
  • Persistent chat history or long-term memory (TODO comments in code)
  • Multi-agent orchestration (single agent instance per yiemAgent struct)
  • Embedding generation or retrieval-augmented generation (RAG)
  • Natural language-to-code generation or execution sandboxes

Dependencies

  • Julia Standard Library: Dates, UUIDs, Base.Threads
  • External Packages: JSON, DataStructures, HTTP, PrettyPrinting, Serialization, DataFrames
  • Internal Package: GeneralUtils (project-specific utility library)
  • Optional: NATS (MCP server communication), LibPQ (PostgreSQL)

Deployment Constraints

  • NFR-001: Library designed for embedded use in Docker containers (MicroK8s cluster, per NFR-501 from template)
  • NFR-002: Must support Julia 1.9+ for module include/export semantics compatibility
  • NFR-003: Thread-safe channel operations; single-agent instance processes messages sequentially on background @spawn task

3. Functional Requirements (FR)

FR-001: Agent Message Processing

The agent shall process user messages through an asynchronous loop that:

  • Accepts messages via inputChannel (capacity 16) and followUpChannel (capacity 32)
  • Prioritizes inputChannel messages over followUpChannel messages
  • Feeds responses to outputChannel (capacity 16) in OpenAI message format
  • Exits cleanly on :shutdown signal

Traceability: US-001, US-003

FR-002: LLM Model Agnosticism

The agent shall accept a pluggable llmCall function that:

  • Receives formatted messages and returns an LLM response dict
  • The response dict may contain message.tool_calls (LMStudio format) or content blocks (OpenAI format)
  • The framework extracts tool calls regardless of response format

Traceability: US-005

FR-003: Tool Call Execution Loop

The agent shall automatically execute tool calls returned by the LLM:

  • Extract tool calls via _extractToolCalls() which supports both message.tool_calls and content[{type="tool_calls"}] formats
  • Build agentContext via prepareContext() (pluggable hook)
  • Format messages via formatMsgForLLM() to OpenAI format
  • Extract tool calls → loop: execute tool calls → append results to history → call LLM again
  • Break loop when LLM response has no tool calls
  • Support terminate flag: if toolResultBatch.terminate == true, break loop and return final response

Traceability: US-003

FR-004: Tool Discovery and Registration

The agent shall:

  • Query MCP server via mcpserver("tools/list") (JSON-RPC 2.0) to discover tools
  • Support pagination via nextCursor field
  • Wrap each MCP tool definition as an agentTool with execute hook that calls mcpserver("tools/call", name, args, sessionId)
  • Register a builtin listTools tool that triggers runtime discovery and lists all available tools
  • Skip tools already registered (idempotent)

Traceability: US-002

FR-005: Tool Call Lifecycle Hooks

The agent shall support two lifecycle hooks:

  • beforeToolCall(beforeToolCallContext, signal) — can block execution by returning beforeToolCallResult(true, reason)
  • afterToolCall(afterToolCallContext) — can transform result by returning modified agentToolResult
  • Errors from hooks are caught and converted to immediateOutcome/error tool result messages (never throw)

Traceability: US-004

FR-006: Message Type Conversion

The agent shall:

  • Convert internal message types (userMessage, assistantMessage, assistantMessageToolCall, toolResultMessage) to OpenAI format via _userMessageToOpenAI(), _assistantMessageToOpenAI(), _assistantMessageToolCallToOpenAI(), _toolResultMessageToOpenAI()
  • Convert internal messageContent types (textContent, imageContent, reasoningContent) to OpenAI content blocks via _messageContentToBlocks()
  • Convert agentTool definitions to OpenAI function tool format via _toolsToOpenAI()

Traceability: US-001

4. Non-Functional Requirements (NFRs)

4.1 Performance & Scalability

  • NFR-101: Agent loop message processing overhead <500ms per sequential tool call (measured KPI: KPI-001)
  • NFR-102: MCP tool discovery for 50+ tools completes within 2 seconds (measured KPI: KPI-002)
  • NFR-103: Channel buffers prevent unbounded memory growth — inputChannel (16), followUpChannel (32), outputChannel (16)

4.2 Availability & Reliability

  • NFR-201: Agent loop catches all errors via try/catch in _agentLoop() and calls eventSink(errMsg) before exit (measured by event sink logging)
  • NFR-202: prepareToolCall() never throws errors — validation failures return immediateOutcome with error tool result

4.3 Privacy & Security

  • Data Classification: Tool arguments and results may contain PII (user messages); MCP tool results treated as untrusted input
  • No built-in auth/authz: Responsibility of mcpServer implementation and beforeToolCall hook
  • Input validation: JSON schema validation via validateToolArguments() checks required fields only (tools need custom validation via validateRequiredArgs hook)

4.4 Observability & Telemetry

  • Required Logs: agentLoop events (via eventSink) emit state machine steps (_agentLoop 1 through _agentLoop 6), _processMessage steps (1 through 18), prepareToolCall steps (1 through 10)
  • Critical Metrics:
    • agent._state.messages.length — conversation history size (logged at each step)
    • toolExecutionStart/toolExecutionEnd events (via toolExecStartEvent, toolExecEndEvent structs)
  • Retention: No built-in log retention; agent is a library, does not manage external logging

5. Acceptance Conditions

  • FR-001: Agent processes messages through channel system with priority ordering (inputChannel > followUpChannel)
  • FR-002: llmCall is pluggable; response formats supported include message.tool_calls dict and content array blocks
  • FR-003: Agent loops on tool calls until LLM returns no tool calls or terminate flag is set
  • FR-004: MCP tools are discovered via tools/list with pagination; all registered tools are callable via tools/call
  • FR-005: beforeToolCall hook can block; afterToolCall hook can transform result; errors return error tool result
  • FR-006: All message types (userMessage, assistantMessage, assistantMessageToolCall, toolResultMessage) convert to OpenAI format
  • NFR-101: Message processing overhead <500ms per sequential tool call
  • NFR-102: MCP discovery for 50+ tools completes <2 seconds
  • NFR-201: Agent loop catches errors and exits gracefully without panics