Skip to main content

Declarative AI-agent framework — composable agents, multi-agent orchestration, and a protocol-decoupled server

Project description

aixon

One framework. Declarative agents, multi-agent orchestration, and a protocol-decoupled server.

Test & Publish codecov PyPI Python License: MIT

aixon is a Python framework for building AI-agent systems. Subclass an agent type, declare your LLM and tools as class attributes, and the agent self-registers — no wiring, no routing table. Connect agents into multi-agent graphs with Orchestrator. Serve them over any wire format through a pluggable ProtocolAdapter. Run the whole thing locally or expose it as an API that any OpenAI-compatible client can reach.


Architecture

graph LR
    Client["🤖 Client / LLM"] -->|"HTTP · SSE"| SA["Server<br/>(ProtocolAdapter)"]
    SA --> R["Registry"]
    R --> A["Agent<br/>(LLMAgent · ToolAgent · Orchestrator)"]
    A --> LLM["LLM<br/>(Provider)"]
    A --> T["Tools<br/>(Retriever · Connector · Agent)"]
    A --> O["Orchestrator<br/>→ nodes (Agents)"]

    style SA fill:#4f46e5,color:#fff,stroke:none
    style A fill:#7c3aed,color:#fff,stroke:none
    style LLM fill:#9333ea,color:#fff,stroke:none
    style T fill:#a855f7,color:#fff,stroke:none

The neutral boundary is the key design principle: every agent speaks only Message[] in and Message/Chunk out — no provider type, no wire type ever crosses into the agent runtime. Protocol adapters translate on the outside; provider SDKs stay hidden inside LLM.


Installation

pip install aixon          # core: langchain + langgraph — agents work out of the box

langchain/langchain-core/langgraph are mandatory core dependencies. The optional extras add the outer layers:

pip install "aixon[server]"            # FastAPI + uvicorn + httpx — serve agents as an API
pip install "aixon[cli]"               # click + openai — the `aixon` command + remote chat
pip install "aixon[openai]"            # OpenAI provider binding (langchain-openai)
pip install "aixon[anthropic]"         # Anthropic provider binding
pip install "aixon[google]"            # Google provider binding
pip install "aixon[retrieval]"         # httpx — Connector / HttpToolConnector
pip install "aixon[openai-embedding]"  # langchain-openai — OpenAIEmbedding
pip install "aixon[weaviate]"          # Weaviate vector-store Retriever
pip install "aixon[ragie]"             # Ragie managed-RAG Retriever
pip install "aixon[tavily]"            # Tavily web-search Retriever
pip install "aixon[rerank]"            # flashrank reranking (for Weaviate)
pip install "aixon[tiktoken]"          # token counting for the server `usage` field
pip install "aixon[all]"               # everything above

60-second quickstart

# 1. Scaffold a consumer project
aixon new my-agents
cd my-agents
pip install -e ".[all]"

# 2. Start the interactive chat
aixon chat

# 3. Or serve the OpenAI-compatible API
aixon serve

Or inline — no scaffolding needed:

# agents/hello.py
from aixon import LLMAgent, LLM

class HelloAgent(LLMAgent):
    llm = LLM("gpt-4o-mini", temperature=0.2)
    description = "Greets the user"
    prompt = "You are a concise greeter. Reply in one sentence."
# main.py
from aixon import autodiscover, Message
from aixon.registry import get_registry

autodiscover("agents")
agent = get_registry().resolve("helloagent")
reply = agent.invoke([Message(role="user", content="Hi!")])
print(reply.content)
python main.py
# → Hi there! How can I help you today?

The Agent model

Everything in aixon is an Agent — a single callable unit with a uniform interface:

agent.invoke(messages: list[Message])  -> Message
agent.stream(messages: list[Message])  -> Iterator[Chunk]
agent.ainvoke(messages: list[Message]) -> Message            # async
agent.astream(messages: list[Message]) -> AsyncIterator[Chunk]
agent.as_tool(name=None, description=None) -> AgentTool

Sync is the default; ainvoke/astream are additive and run non-blocking (native for LLMAgent/ToolAgent/Orchestrator, a thread-bridge for custom sync agents). The server awaits them, so concurrent requests don't serialize.

Three concrete subtypes cover the common cases. Pick the one that matches what you need:

Subtype When to use Suffix required
LLMAgent Direct LLM call — no tools, no loop *Agent
ToolAgent LLM + tool-calling loop (LangGraph create_agent) *Agent
Orchestrator Multiple agents coordinated by a graph *Orchestrator

Suffix rule: every concrete subclass name must end with its declared suffix. Violating it raises NamingError at import time — before the server starts.

class Greeter(LLMAgent):    # ← raises NamingError: missing 'Agent' suffix
    ...

class GreeterAgent(LLMAgent):  # ← correct
    ...

LLMAgent — direct LLM call

from aixon import LLMAgent, LLM

class PlannerAgent(LLMAgent):
    llm         = LLM("gpt-4o-mini", temperature=0.2)
    description = "Strategic planner"
    prompt      = "You plan step-by-step actions for complex goals."

Attributes:

Attribute Type Description
llm LLM Required. The language model to use.
prompt str Optional system prompt prepended to every conversation.
description str Human-readable purpose (shown in aixon list).
name str Registry name (defaults to lowercased class name).
aliases list[str] Alternate names for registry resolution.
hidden bool Exclude from aixon chat menu and public() listing.

aixon list output (no header, one agent per line):

greeteragent  [LLMAgent]  Friendly greeter

See docs/agents.md for ToolAgent and full API reference.


Orchestrator — multi-agent graphs

from aixon import Orchestrator, LLM

class SupportOrchestrator(Orchestrator):
    supervisor = LLM("gpt-4o-mini")          # routes each turn to a worker
    agents     = [BillingAgent, TechAgent, PlannerAgent]   # your own LLMAgent/ToolAgent classes

Three tiers — pick by complexity. See docs/orchestrator.md.


Retrieval — Retriever, Connector, Embedding

Retriever is the base class for any agent that fetches context. Name it with a *Retriever suffix and declare type_access to control read/write permissions (TypeAccess.READ, TypeAccess.WRITE, or TypeAccess.ALL).

from aixon import Retriever, TypeAccess

class LibraryRetriever(Retriever):
    description = "Fetches relevant documents from the knowledge base"
    type_access = TypeAccess.READ

Every Retriever has a sync search and a native async asearch; as_tool() returns a dual tool that works on both the sync and async agent paths.

Connector is an HTTP base class for wrapping external APIs (base_url_env / auth_token_env, sync get/post and async aget/apost). HttpToolConnector builds on it for HTTP-JSON tool servers.

Embedding is the vector-embedding ABC; the built-in implementation is OpenAIEmbedding.

Vendor retrievers ship behind optional extras — each a neutral Retriever, lazy (the vendor SDK is imported only on use) and async-native:

Retriever Extra Backend
WeaviateRetriever aixon[weaviate] Weaviate vector store (+ aixon[rerank] for flashrank)
RagieRetriever aixon[ragie] Ragie managed RAG
TavilyRetriever aixon[tavily] Tavily web search
from aixon import Retriever, TypeAccess, Connector, Embedding, OpenAIEmbedding

See docs/retrieval.md (ABCs) and docs/retrievers.md (vendor backends).


Server

from aixon import Server, autodiscover

autodiscover("agents")
server = Server()
server.serve(host="0.0.0.0", port=8000)

Any OpenAI-compatible client works out of the box:

from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="test")
response = client.chat.completions.create(
    model="planneragent",
    messages=[{"role": "user", "content": "Plan a trip to Tokyo."}],
)

See docs/server.md for Anthropic adapter, auth, and SSE streaming.


Environment variables

Variable Default Description
LOG_LEVEL INFO Framework log level: DEBUG, INFO, WARNING, ERROR.
AUTH_API_KEY (disabled) Bearer token for the server. Unset = no auth. Multiple keys comma-separated.
OPENAI_API_KEY (required for OpenAI) API key for the OpenAI provider.
ANTHROPIC_API_KEY (required for Anthropic) API key for the Anthropic provider.
GOOGLE_API_KEY (required for Google) API key for the Google provider.

Naming conventions

Suffix violations raise NamingError at import time — the server never starts with a mis-named class.

Base class Required suffix Example
LLMAgent *Agent PlannerAgent
ToolAgent *Agent DiagnosisAgent
Orchestrator *Orchestrator SupportOrchestrator
Retriever *Retriever LibraryRetriever
Connector *Connector CRMConnector

Abstract intermediate classes (declared with abstract=True) are exempt and never registered.


Documentation

  • Architecture — layers, neutral boundary, protocol decoupling
  • AgentsLLMAgent, ToolAgent, declarative API, as_tool, async
  • Orchestrator — three tiers, entry/topology, branching, recursion guards
  • ServerProtocolAdapter, adapters, auth, SSE
  • RetrievalRetriever, Embedding, Connector
  • Vendor retrieversWeaviate, Ragie, Tavily
  • CLIchat, new, serve, list
  • Quickstart — consumer project walkthrough
  • Example — a complete multi-agent support assistant, runnable offline

Dependencies

langchain             >= 1.0    (core)
langchain-core        >= 1.0    (core)
langgraph             >= 1.0    (core)
fastapi / uvicorn / pydantic    (server extra)
httpx                 >= 0.27   (server / retrieval extra)
click / openai                  (cli extra — `aixon` command + remote chat)
langchain-openai      >= 0.2    (openai / openai-embedding extra)
langchain-anthropic   >= 0.2    (anthropic extra)
langchain-google-genai >= 2.0   (google extra)
weaviate-client / langchain-weaviate  (weaviate extra)
ragie                 >= 2      (ragie extra)
tavily-python         >= 0.7    (tavily extra)
flashrank             >= 0.2    (rerank extra)
tiktoken              >= 0.7    (tiktoken extra)

Author

Jorge Henrique Moreira Santana
Electrical Engineer, Postgraduate in Artificial Intelligence
LinkedIn · ti@zeusagro.com


License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aixon-0.1.5.tar.gz (166.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aixon-0.1.5-py3-none-any.whl (72.6 kB view details)

Uploaded Python 3

File details

Details for the file aixon-0.1.5.tar.gz.

File metadata

  • Download URL: aixon-0.1.5.tar.gz
  • Upload date:
  • Size: 166.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for aixon-0.1.5.tar.gz
Algorithm Hash digest
SHA256 541ecf26ab87f5a530f17f875bb98ea765f2c6b0f25e7b739a0507cf3f14dc27
MD5 fb1863ec707249590195b550e40c06ea
BLAKE2b-256 12910bf9aaaced234ca9ace8d90928d61485992a5232461949532d3de6769dde

See more details on using hashes here.

Provenance

The following attestation bundles were made for aixon-0.1.5.tar.gz:

Publisher: publish.yml on JorgeHSantana/aixon

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file aixon-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: aixon-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 72.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for aixon-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 c1cee53ea29f0d55c69747fc66939934168f58cde281904fbeb35fdf2b1c09bf
MD5 4cfe9369f641ced4dc79513c7237c012
BLAKE2b-256 ab4c75077bcffd64f1844cb452910a02388866fd606fd781faa19fda6ac62e3b

See more details on using hashes here.

Provenance

The following attestation bundles were made for aixon-0.1.5-py3-none-any.whl:

Publisher: publish.yml on JorgeHSantana/aixon

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page