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.0.tar.gz (122.1 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.0-py3-none-any.whl (66.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: aixon-0.1.0.tar.gz
  • Upload date:
  • Size: 122.1 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.0.tar.gz
Algorithm Hash digest
SHA256 908339736f57877b9986df36ec0251b8113d842ad301a2f21c41c64ec0003f41
MD5 0f3f3ff15909c084768be0044e41da47
BLAKE2b-256 8341baa0b63f0919f6db34cd2d44fc6526c8f2a96244b8d798d2ebfbf6bfcf64

See more details on using hashes here.

Provenance

The following attestation bundles were made for aixon-0.1.0.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.0-py3-none-any.whl.

File metadata

  • Download URL: aixon-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 66.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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d01eb19c93a844dba585918d32190607813ae4bdeb6671a4ec5e448713eba727
MD5 d4f9e9dd52a088e77a4e6be9eff85a5e
BLAKE2b-256 16e0e5040c817af40eb5f406015ba553e1797adbda7cabce956b84db8a5360f8

See more details on using hashes here.

Provenance

The following attestation bundles were made for aixon-0.1.0-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