LLM Tornado for .NET
A .NET SDK for building provider-flexible AI agents, tool-enabled conversations, and graph-based workflows.
- Source repo
- lofcz/LLMTornado
- Stars
- ★ 651
- Last updated
- 1d ago
- License
- MIT
- Primary language
- C#
- FA score
- 50/100 · Major gaps
At a glance
- How it runs
- Works with
- Universal · cross-platformOpenAI API · Claude APICodex (Partial support)
- Cost
- Free software; you pay for model usage
- Setup effort
- Medium · a few setup steps
- You'll need
- Typical use
- A C# backend team needs to switch among OpenAI, Anthropic, Google, Groq, and other models primarily by changing ChatModel rather than rewriting request code.
- Not a fit if
- Python-only teams unwilling to adopt .NET
- Users wanting a turnkey app without managing multiple provider API keys
- Source review
- 50/100 · Major gaps 2 safety controls not found
What does this agent do, and when should you use it?
LLM Tornado is a provider-agnostic .NET SDK for building AI agents and workflows. Its core API uses TornadoApi, ChatModel, and Conversation for chat, streaming, embeddings, and rich responses, selecting configured credentials by model. LlmTornado.Agents models graph-based coordination with Orchestrator, Runner, and Advancer, including handoffs, parallel execution, and Mermaid export. LlmTornado.Mcp adds Model Context Protocol interoperability, LlmTornado.A2A adds Agent2Agent integration, and a separate package interoperates with Microsoft.Extensions.AI. A .NET application can call hosted providers or point the SDK at local Ollama, vLLM, or LocalAI deployments.
An application configures TornadoApi with one or more LLmProviders and API keys, then creates a Conversation from a ChatModel or model string. After appending system and user messages, it can call GetResponse() for text or GetResponseRich() and StreamResponseRich() for tool calls, multimodal content, and usage metadata. Model-requested Tool or ToolFunction calls can be resolved immediately through FunctionCallHandler and the conversation continued, or handled later. With LlmTornado.Mcp, a client creates an IMcpClient through McpClientFactory.CreateAsync(clientTransport), reads tools with ListTornadoToolsAsync(), passes them to ChatRequest, and executes remote calls through ResolveRemote. For agent workflows, LlmTornado.Agents coordinates specialist agents through an Orchestrator graph, Runner nodes, and Advancer edges; the SDK runs as a NuGet dependency inside a .NET application while the caller supplies hosted or local inference endpoints.
- A C# backend team needs to switch among OpenAI, Anthropic, Google, Groq, and other models primarily by changing ChatModel rather than rewriting request code.
- A .NET developer is building a multi-step workflow and needs Orchestrator, Runner, and Advancer to represent nodes, edges, handoffs, and parallel execution.
- An application team needs models to use weather, internal-service, or other MCP Server tools and wants to convert IMcpClient-discovered tools into Tornado Tool instances.
- A team running Ollama, vLLM, or LocalAI on its own infrastructure needs Conversation requests sent to a custom inference endpoint.
- A developer needs typed function-call parameters and a secondary model fallback for a structured extraction or workflow step, using ToolkitChat, ChatFunction, and ChatPlugin.
How do you install or deploy this agent?
From a .NET project directory, run:
dotnet add package LlmTornadoAdd optional packages as needed:
dotnet add package LlmTornado.Agents
dotnet add package LlmTornado.Mcp
dotnet add package LlmTornado.A2A
dotnet add package LlmTornado.Microsoft.Extensions.AI
dotnet add package LlmTornado.ContribFor hosted providers, supply that provider's API key when constructing TornadoApi. For a local deployment, new TornadoApi(new Uri("http://localhost:11434")) targets the default Ollama port.
How do you use this agent?
A minimal invocation configures a provider and key, then creates a conversation:
TornadoApi api = new TornadoApi(LLmProviders.OpenAi, "OPEN_AI_KEY");
string? response = await api.Chat.CreateConversation("gpt-5-mini")
.AppendUserInput("Hello").GetResponse();
For streamed text, use .StreamResponse(Console.Write). For MCP, install LlmTornado.Mcp, create an IMcpClient with McpClientFactory.CreateAsync(clientTransport), call ListTornadoToolsAsync(), and assign the returned List<Tool> to ChatRequest.Tools.
What are this agent's strengths and limitations?
- A common TornadoApi, ChatModel, and Conversation interface spans multiple providers and can resolve the provider from a model name.
- Agent orchestration explicitly includes Orchestrator, Runner, Advancer, handoffs, parallel execution, and Mermaid export.
- MCP and A2A are available as dedicated NuGet integrations; the MCP example covers discovery, argument inference, remote execution, and returning results to the model.
- It supports rich streaming, immediate or deferred tool resolution, and ResponseRichSafe APIs designed not to throw on network-level failures.
- Adopters must manage each hosted provider's API keys, available models, and network access; the examples do not operate those services for you.
- Provider capabilities are not necessarily identical: detailed endpoint support is tracked in a Feature Matrix, and providers without strict JSON Schema support use a fallback that prefills "{".
- The local-model path depends on an externally running Ollama, vLLM, or LocalAI service; the library supplies connectivity and request transformations rather than model hosting.
- Microsoft.Extensions.AI, MCP, A2A, and agent-orchestration functionality are distributed across optional packages that must be installed and integrated as needed.
How does this agent compare with similar options?
Key facts side by side with the most closely related agents.
| Agent | Source review | Form / cost | Stars | Updated | Language | Full support on |
|---|---|---|---|---|---|---|
| LLM Tornado for .NET This agent | 50 · Major gaps | Library / SDKFree + model costs | ★ 651 | 1d ago | C# | OpenAI API · Claude API |
| Langroid | 70 · Some gaps | Library / SDKFree + model costs | ★ 4.1k | 2d ago | Python | Claude Code · OpenAI API |
| Agent Craft | 49 · Major gaps | CLIFree + model costs | ★ 535 | 10d ago | Python | OpenAI API |
| SmythOS Runtime Environment | 48 · Major gaps | CLIFree + model costs | ★ 1.3k | 7mo ago | TypeScript | OpenAI API · Claude API |
How does FollowAgents rate this agent?
Why each dimension lost points
Evidence shows: README demonstrates API key construction but lacks least privilege or user confirmation mechanisms. Data flow transparency is partial; README mentions request preview/transform but not data flow details. Sensitive data handling mentions API keys but not storage/protection. Dependency security has CI builds but no dependency scanning. External effects mentions tool calls and MCP but not side-effect control. Rollback is absent. Source attribution lists maintainers but unverified. Deductions: no user confirmation, rollback, and weak least privilege evidence.
Evidence shows: README and code examples are consistent, but no full API documentation. Dependency availability: NuGet packages exist but unverified. Failure messages: safe APIs mentioned but error handling details lacking. Deduction: insufficient failure message detail.
Evidence shows: README targets developers with multiple scenario examples. Capability boundaries list features but not limitations. Trigger precision is clear in tool call examples but not comprehensive. Environment fit supports multiple .NET frameworks and local deployments. Deduction: trigger precision and boundary descriptions incomplete.
Evidence shows: README is well-structured, install notes clear, naming stable, examples abundant, but known limitations not explicit. License is MIT, changelog in News section, maintenance responsibility clear. Deduction: known limitations not listed.
Evidence shows: Output usability offers multiple response formats. Marginal value enhanced by multi-provider support. Cost-benefit: open-source free but no performance data. Deduction: cost-benefit evidence insufficient.
Evidence shows: README claims have links but no independent verification. Cross-source corroboration has external references but not deep. Fact-inference separation: README mixes facts and promotion. Deduction: cross-verification and fact separation insufficient.
- Not found in source: confirmation before actingTurn on (or add) a confirmation step before it acts, and try it in a sandbox or test environment before real data.
- Not found in source: rollback or recovery pathBack up first, or work on a git branch or snapshot, so its changes can be undone.
- API key handling lacks secure storage guidance; use with caution.
- No user confirmation mechanism; tool calls may execute external actions automatically.
- Dependency security scanning not mentioned; verify yourself.
Recent releases
Latest entries from the project's GitHub Releases. Notes are quoted from upstream as written, not rewritten or tested by FollowAgents.
-
v3.8.82 Release v3.8.82
Release notes excerpt
What's Changed - Fix release version persistence and NuGet publish retries - Implement Claude November API sync and resilient message thread sessions Updated Projects LlmTornado.Microsoft.Extensions.AI.csproj -> 1.1.73 LlmTornado.csproj -> 3.8.82 LlmTornado.Agents.csproj -> 1.0.69 LlmTornado.A2A.csproj -> 1.0.57 LlmTornado.VectorDatabases.Pinecone.csproj -> 1.0.7 LlmTornado.Mcp.csproj -> 1.1.67View on GitHub ↗ -
v3.8.81 Release v3.8.81
Release notes excerpt
What's Changed - fix(anthropic): treat raw base64 images starting with '/' as base64, not URLs - Start Puppeteer on the installed Chrome with its sandbox on - fix(chat): send every stop sequence to Anthropic and Cohere - fix(mistral): mark retired Mistral model constants obsolete - fix(xai): format search parameter dates as yyyy-MM-dd - chore(video): mark Veo 3.1 preview models obsolete after the October 22, 2026 shutdown - fix(images): drop response_format and input_fidelity from gpt-image edit requests - fix(embeddings): serialize Upstage embedding requests …View on GitHub ↗ -
v3.8.80 Release v3.8.80
Release notes excerpt
What's Changed - fix: implement LocalDocumentStore.DeleteDocument - fix(retrieval): look up parent documents by parent_id in ParentChildDocumentRetriever.Search - fix(chroma): send the new embedding in UpdateDocuments - fix(qdrant): apply NotEqual and NotIn metadata filters - fix(vectordb): support $and/$or metadata filters in Faiss and PgVector - fix: send ChatRequest.Seed to Mistral as random_seed - feat: add TornadoApiRouter to route models to named TornadoApi instances - Cohere streams: keep the length finish reason of a stream with tool calls …View on GitHub ↗