┌─────────────────────────────────────────────────────────────────────┐
│ FlowLLM SDK │
│ (Simple Developer API) │
├─────────────────────────────────────────────────────────────────────┤
│ defineAgent() │ defineTool() │ Conversation API │
└────────────┬────────────────────────────────────────────────────────┘
│
┌────────┴────────┐
│ │
┌───▼─────────┐ ┌────▼──────────┐
│ Agent │ │ ToolRegistry │
│ │ │ │
│ • Execute │ │ • Register │
│ • Stream │ │ • Execute │
│ • Memory │ │ • Validate │
└───┬─────────┘ └────┬──────────┘
│ │
│ ┌────────────┘
│ │
┌───▼────▼─────┐ ┌─────────────┐ ┌──────────────┐
│ LLMClient │───────│ Middleware │ │ MCPClient │
│ │ │ │ │ │
│ • Chat │ │ • onRequest │ │ • Connect │
│ • Stream │ │ • onResponse│ │ • Discover │
│ • Retry │ │ • onError │ │ • Execute │
└───┬──────────┘ └─────────────┘ └──────┬───────┘
│ │
│ ┌──────────────┐ ┌─────────────┐ │
│ │ CostTracker │ │ Memory │ │
│ │ │ │ │ │
│ │ • Track │ │ • Add │ │
│ │ • GetTotal │ │ • Get │ │
│ │ • Reset │ │ • Trim │ │
│ └──────────────┘ └─────────────┘ │
│ │
┌───▼────────────────────────────┐ ┌────────────▼──────────┐
│ LLM Providers │ │ MCP Protocol │
├────────────────────────────────┤ ├───────────────────────┤
│ • OpenAI (GPT-4, GPT-4o) │ │ • Stdio Transport │
│ • Anthropic (Claude 3/3.5) │ │ • Tool Discovery │
│ • Google (Gemini Pro/1.5) │ │ • Type Conversion │
└────────────────────────────────┘ └───────────────────────┘
User Message
│
▼
┌─────────────────┐
│ Agent.execute │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Add to Memory │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Get History │
└────────┬────────┘
│
▼
┌─────────────────┐
│ LLMClient.chat │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Provider API │
└────────┬────────┘
│
▼
┌─────────────────┐
│ LLM Response │
└────────┬────────┘
│
┌────┴────┐
│ │
▼ ▼
Tool Calls? No
│ │
Yes │
│ │
▼ │
┌─────────────────┐
│ Execute Tools │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Add to Memory │
└────────┬────────┘
│
└──────┐
│
▼
Loop Again
│
▼
┌──────────────┐
│ Final Result │
└──────────────┘
Tool Call
│
▼
┌──────────────────┐
│ ToolRegistry │
│ .execute() │
└────────┬─────────┘
│
┌────┴────┐
│ │
▼ ▼
MCP Tool? Custom Tool?
│ │
▼ ▼
┌─────────┐ ┌──────────┐
│ MCP │ │ Custom │
│ Client │ │ Function │
└────┬────┘ └─────┬────┘
│ │
└─────┬──────┘
│
▼
┌─────────────┐
│ Tool Result │
└─────────────┘
User Message
│
▼
┌────────────────┐
│ Agent.stream() │
└───────┬────────┘
│
▼
┌────────────────┐
│ LLMClient │
│ .stream() │
└───────┬────────┘
│
▼
┌────────────────┐
│ Provider │
│ .stream() │
└───────┬────────┘
│
▼
┌────────┐
│ Chunk │◄──┐
└───┬────┘ │
│ │
▼ │
Yield to More
User Chunks?
│ │
└────────┘
Every LLM Call
│
▼
┌──────────────────┐
│ LLM Response │
│ (with usage) │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ CostTracker │
│ .track() │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Calculate Cost │
│ (tokens × rate) │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Update Total │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Call onCost() │
│ callback │
└──────────────────┘
┌──────────┐ uses ┌─────────────┐
│ Agent │──────────────►│ LLMClient │
└────┬─────┘ └──────┬──────┘
│ │
│ uses │ uses
│ │
▼ ▼
┌──────────┐ ┌─────────────┐
│ Memory │ │ Provider │
└──────────┘ └─────────────┘
│
│ uses
│
▼
┌──────────┐ ┌─────────────┐
│ Tool │─────uses────►│ MCPClient │
│ Registry │ └─────────────┘
└──────────┘
flowllm (Main SDK)
│
├──► @flowllm/core
│ │
│ ├──► pino (logging)
│ └──► zod (validation)
│
├──► @flowllm/providers
│ │
│ ├──► @flowllm/core
│ ├──► openai
│ ├──► @anthropic-ai/sdk
│ ├──► @google/generative-ai
│ └──► tiktoken
│
└──► @flowllm/mcp
│
├──► @flowllm/core
└──► @modelcontextprotocol/sdk
1. User calls agent.execute()
│
▼
2. Agent adds message to memory
│
▼
3. Agent retrieves conversation history
│
▼
4. LLMClient executes request middleware
│
▼
5. RetryHandler wraps provider call
│
▼
6. Provider makes API call
│
▼
7. Provider maps response to unified format
│
▼
8. LLMClient executes response middleware
│
▼
9. CostTracker tracks usage and cost
│
▼
10. Agent checks for tool calls
│
┌────┴────┐
Yes No
│ │
▼ ▼
11a. Execute 11b. Return
tools final
│ response
▼
12. Add tool results to memory
│
▼
13. Loop back to step 3
(if under max iterations)
This architecture provides:
- ✅ Clear separation of concerns
- ✅ Easy to extend (add providers, middleware)
- ✅ Type-safe throughout
- ✅ Production-ready features built-in
- ✅ Simple developer API
- ✅ Unified interface across providers