axel-protocol 2.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- axel_protocol-2.1.0/.github/workflows/ci.yml +87 -0
- axel_protocol-2.1.0/.gitignore +43 -0
- axel_protocol-2.1.0/CHANGELOG.md +41 -0
- axel_protocol-2.1.0/CONTRIBUTING.md +115 -0
- axel_protocol-2.1.0/Dockerfile +44 -0
- axel_protocol-2.1.0/LICENSE +21 -0
- axel_protocol-2.1.0/PKG-INFO +523 -0
- axel_protocol-2.1.0/README.md +435 -0
- axel_protocol-2.1.0/axel/__init__.py +80 -0
- axel_protocol-2.1.0/axel/adapters/__init__.py +148 -0
- axel_protocol-2.1.0/axel/adapters/bedrock.py +153 -0
- axel_protocol-2.1.0/axel/adapters/cohere.py +121 -0
- axel_protocol-2.1.0/axel/adapters/gemini.py +119 -0
- axel_protocol-2.1.0/axel/adapters/groq.py +122 -0
- axel_protocol-2.1.0/axel/adapters/litellm.py +148 -0
- axel_protocol-2.1.0/axel/adapters/mistral.py +117 -0
- axel_protocol-2.1.0/axel/adapters/together.py +125 -0
- axel_protocol-2.1.0/axel/cli.py +532 -0
- axel_protocol-2.1.0/axel/client.py +461 -0
- axel_protocol-2.1.0/axel/core.py +674 -0
- axel_protocol-2.1.0/axel/learning.py +687 -0
- axel_protocol-2.1.0/axel/persistence.py +376 -0
- axel_protocol-2.1.0/axel/server.py +1072 -0
- axel_protocol-2.1.0/axel/static/monitor.html +595 -0
- axel_protocol-2.1.0/axel/testing.py +273 -0
- axel_protocol-2.1.0/axel/universal.py +1378 -0
- axel_protocol-2.1.0/docker-compose.yml +47 -0
- axel_protocol-2.1.0/docs/message-schemas.md +272 -0
- axel_protocol-2.1.0/examples/demo_live.py +255 -0
- axel_protocol-2.1.0/examples/monitor.html +595 -0
- axel_protocol-2.1.0/pyproject.toml +112 -0
- axel_protocol-2.1.0/tests/__init__.py +0 -0
- axel_protocol-2.1.0/tests/test_adapters.py +196 -0
- axel_protocol-2.1.0/tests/test_client.py +165 -0
- axel_protocol-2.1.0/tests/test_core.py +214 -0
- axel_protocol-2.1.0/tests/test_new_features.py +553 -0
- axel_protocol-2.1.0/tests/test_server.py +216 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, develop]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
|
|
11
|
+
# ── Lint & format ────────────────────────────────────────────────
|
|
12
|
+
lint:
|
|
13
|
+
name: Lint (ruff)
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
- run: pip install ruff
|
|
21
|
+
- run: ruff check .
|
|
22
|
+
- run: ruff format --check .
|
|
23
|
+
|
|
24
|
+
# ── Unit + integration tests ─────────────────────────────────────
|
|
25
|
+
test:
|
|
26
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
strategy:
|
|
29
|
+
fail-fast: false
|
|
30
|
+
matrix:
|
|
31
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
32
|
+
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v4
|
|
35
|
+
|
|
36
|
+
- uses: actions/setup-python@v5
|
|
37
|
+
with:
|
|
38
|
+
python-version: ${{ matrix.python-version }}
|
|
39
|
+
|
|
40
|
+
- name: Install package + dev deps
|
|
41
|
+
run: pip install -e ".[dev]"
|
|
42
|
+
|
|
43
|
+
- name: Run tests
|
|
44
|
+
run: pytest tests/ -v --tb=short
|
|
45
|
+
|
|
46
|
+
- name: Upload coverage (optional)
|
|
47
|
+
if: matrix.python-version == '3.12'
|
|
48
|
+
run: |
|
|
49
|
+
pip install pytest-cov
|
|
50
|
+
pytest tests/ --cov=axel --cov-report=xml --cov-report=term-missing
|
|
51
|
+
continue-on-error: true
|
|
52
|
+
|
|
53
|
+
# ── Docker build check ───────────────────────────────────────────
|
|
54
|
+
docker:
|
|
55
|
+
name: Docker build
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
steps:
|
|
58
|
+
- uses: actions/checkout@v4
|
|
59
|
+
- name: Build image
|
|
60
|
+
run: docker build -t axel-protocol:ci .
|
|
61
|
+
- name: Smoke test container
|
|
62
|
+
run: |
|
|
63
|
+
docker run -d --name axel-ci -p 7331:7331 axel-protocol:ci
|
|
64
|
+
sleep 5
|
|
65
|
+
curl -f http://localhost:7331/status
|
|
66
|
+
docker stop axel-ci
|
|
67
|
+
|
|
68
|
+
# ── PyPI publish (only on version tags) ──────────────────────────
|
|
69
|
+
publish:
|
|
70
|
+
name: Publish to PyPI
|
|
71
|
+
needs: [lint, test]
|
|
72
|
+
runs-on: ubuntu-latest
|
|
73
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
74
|
+
environment: pypi
|
|
75
|
+
permissions:
|
|
76
|
+
id-token: write # required for trusted publishing
|
|
77
|
+
|
|
78
|
+
steps:
|
|
79
|
+
- uses: actions/checkout@v4
|
|
80
|
+
- uses: actions/setup-python@v5
|
|
81
|
+
with:
|
|
82
|
+
python-version: "3.12"
|
|
83
|
+
- run: pip install build
|
|
84
|
+
- run: python -m build
|
|
85
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
86
|
+
# Uses OIDC trusted publishing — no API token needed
|
|
87
|
+
# Set up at: https://pypi.org/manage/account/publishing/
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
dist/
|
|
9
|
+
*.egg-info/
|
|
10
|
+
.eggs/
|
|
11
|
+
.env
|
|
12
|
+
.venv
|
|
13
|
+
venv/
|
|
14
|
+
env/
|
|
15
|
+
*.egg
|
|
16
|
+
|
|
17
|
+
# Testing
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.coverage
|
|
20
|
+
coverage.xml
|
|
21
|
+
htmlcov/
|
|
22
|
+
.mypy_cache/
|
|
23
|
+
.ruff_cache/
|
|
24
|
+
|
|
25
|
+
# AXEL runtime files
|
|
26
|
+
~/.axel/
|
|
27
|
+
*.jsonl
|
|
28
|
+
session_log.jsonl
|
|
29
|
+
|
|
30
|
+
# IDE
|
|
31
|
+
.idea/
|
|
32
|
+
.vscode/
|
|
33
|
+
*.swp
|
|
34
|
+
*.swo
|
|
35
|
+
.DS_Store
|
|
36
|
+
|
|
37
|
+
# Docker
|
|
38
|
+
.docker/
|
|
39
|
+
|
|
40
|
+
# Secrets — never commit these
|
|
41
|
+
.env.local
|
|
42
|
+
*.key
|
|
43
|
+
*_secret*
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to AXEL are documented here.
|
|
4
|
+
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## [2.0.0] — 2024-12
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **AXEL Network Server** (`axel.server`) — FastAPI HTTP hub for real multi-LLM networks
|
|
12
|
+
- **AXELClient SDK** (`axel.client`) — pure Python stdlib client, zero extra dependencies
|
|
13
|
+
- **AXELAgent base class** — `@task_handler` decorator for self-contained agents
|
|
14
|
+
- **LLM Adapters** — MockAdapter, AnthropicAdapter, OpenAIAdapter, OllamaAdapter
|
|
15
|
+
- **Chain pipeline** (`CH` message type) — sequential multi-step execution with context passing
|
|
16
|
+
- **Server-Sent Events stream** (`/stream`) — real-time event feed for dashboards
|
|
17
|
+
- **Live monitor dashboard** (`examples/monitor.html`) — browser-based SSE dashboard
|
|
18
|
+
- **6 new v2 message types** — `AN`, `CP`, `SP`, `SB`, `PB`, `CH`
|
|
19
|
+
- `/agents/announce` — agent registration endpoint
|
|
20
|
+
- `/discover/<action>` — capability-based agent discovery
|
|
21
|
+
- `/channels/subscribe` and `/channels/publish` — pub/sub system
|
|
22
|
+
- `/execute` — synchronous task + chain execution endpoint
|
|
23
|
+
- Long-poll inbox (`/inbox/{id}`) with configurable timeout
|
|
24
|
+
- Persistent memory path configurable via `AXEL_MEMORY_PATH`
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- Protocol version bumped to `v: "2"`
|
|
28
|
+
- `AXELBuilder` now the canonical message factory (replaces raw dict construction)
|
|
29
|
+
- SmartMemory BM25 search now normalises scores across corpus
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## [1.0.0] — 2024-10
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
- **AXEL protocol spec** — 17 core message types (TK, OK, ER, LS, MR, MW, QR, PP, PA, HK, NT, FT, ST, AB, RT, BK, RS)
|
|
37
|
+
- **axel.core** — `AXELMessage`, `AXELBuilder`, message parsing and validation
|
|
38
|
+
- **SmartMemory** — in-process shared memory with BM25 search and confidence decay
|
|
39
|
+
- **AXELRegistry** — cross-model agent discovery and capability matching
|
|
40
|
+
- **axel_dashboard.html** — first-generation in-browser dashboard
|
|
41
|
+
- **Cowork plugin** (`axel-protocol`) — slash commands for Claude: `/axel-init`, `/axel-task`, `/axel-status`, `/axel-lesson`, `/axel-memory`, `/axel-announce`, `/axel-discover`
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Contributing to AXEL
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in making AXEL better. Contributions of all sizes are welcome — from typo fixes to new LLM adapters.
|
|
4
|
+
|
|
5
|
+
## Ways to contribute
|
|
6
|
+
|
|
7
|
+
**New LLM adapters** are the highest-impact contribution. Every new adapter connects AXEL to a new family of models. Priority targets:
|
|
8
|
+
- Google Gemini (`GeminiAdapter`)
|
|
9
|
+
- Mistral AI (`MistralAdapter`)
|
|
10
|
+
- Cohere (`CohereAdapter`)
|
|
11
|
+
- Together AI (`TogetherAdapter`)
|
|
12
|
+
- Groq (`GroqAdapter`)
|
|
13
|
+
|
|
14
|
+
**Memory backends** — the current `SmartMemory` is in-process dict + JSON file. Production deployments need:
|
|
15
|
+
- `RedisMemory` — shared across multiple server instances
|
|
16
|
+
- `SQLiteMemory` — persistent, zero infrastructure
|
|
17
|
+
- `PostgresMemory` — for larger deployments
|
|
18
|
+
|
|
19
|
+
**Agent templates** — pre-built `AXELAgent` subclasses for common roles:
|
|
20
|
+
- `ResearcherAgent` — wraps search APIs (Tavily, Perplexity, SerpAPI)
|
|
21
|
+
- `CoderAgent` — integrates code execution (E2B, local subprocess)
|
|
22
|
+
- `ReviewerAgent` — standardised quality scoring rubric
|
|
23
|
+
|
|
24
|
+
**Language clients** — the Python client is pure stdlib. Ports needed:
|
|
25
|
+
- TypeScript/Node.js
|
|
26
|
+
- Rust
|
|
27
|
+
- Go
|
|
28
|
+
|
|
29
|
+
**AXEL Studio** — a visual drag-and-drop network editor for designing multi-agent pipelines.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Getting started
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
git clone https://github.com/sectorx/axel-protocol
|
|
37
|
+
cd axel-protocol
|
|
38
|
+
pip install -e ".[dev]"
|
|
39
|
+
|
|
40
|
+
# Run tests
|
|
41
|
+
pytest
|
|
42
|
+
|
|
43
|
+
# Run the demo (no API keys needed)
|
|
44
|
+
python examples/demo_live.py
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Adding an adapter
|
|
50
|
+
|
|
51
|
+
An adapter wraps a single LLM provider. It receives an AXEL `TK` message, calls the provider's API, and returns a result dict.
|
|
52
|
+
|
|
53
|
+
Create `axel/adapters/<name>.py`:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from axel.server import BaseAdapter
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class GeminiAdapter(BaseAdapter):
|
|
60
|
+
"""Google Gemini adapter for the AXEL bridge."""
|
|
61
|
+
|
|
62
|
+
provider = "google"
|
|
63
|
+
|
|
64
|
+
def __init__(self, agent_id: str, model: str, api_key: str, caps: list[str] = None):
|
|
65
|
+
super().__init__(agent_id, model, caps)
|
|
66
|
+
import google.generativeai as genai
|
|
67
|
+
genai.configure(api_key=api_key)
|
|
68
|
+
self._client = genai.GenerativeModel(model)
|
|
69
|
+
|
|
70
|
+
def execute(self, action: str, args: dict, ctx: dict) -> dict:
|
|
71
|
+
prompt = self._build_prompt(action, args, ctx)
|
|
72
|
+
response = self._client.generate_content(prompt)
|
|
73
|
+
return {"result": response.text, "action": action}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Then register it in `axel/server.py`'s `AXELBridge.add_*` factory methods and add tests in `tests/test_adapters.py`.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Code style
|
|
81
|
+
|
|
82
|
+
- Python 3.10+ type hints where practical
|
|
83
|
+
- `ruff` for linting and formatting: `ruff check . && ruff format .`
|
|
84
|
+
- Docstrings for public classes and methods
|
|
85
|
+
- Tests for all new adapters and backends
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Pull request process
|
|
90
|
+
|
|
91
|
+
1. Fork the repo and create a branch: `git checkout -b feat/gemini-adapter`
|
|
92
|
+
2. Write your code and tests
|
|
93
|
+
3. Run `pytest` — all tests must pass
|
|
94
|
+
4. Run `ruff check . && ruff format .` — no lint errors
|
|
95
|
+
5. Open a PR against `main` with a clear description of what you built and why
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Reporting bugs
|
|
100
|
+
|
|
101
|
+
Open a GitHub issue with:
|
|
102
|
+
- Python version and OS
|
|
103
|
+
- AXEL version (`pip show axel-protocol`)
|
|
104
|
+
- Minimal reproduction script
|
|
105
|
+
- Full error traceback
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Questions
|
|
110
|
+
|
|
111
|
+
Open a Discussion on GitHub or start a thread in the community Discord (link in repo sidebar once live).
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
*AXEL is MIT-licensed. By contributing you agree your contributions will be released under the same license.*
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
FROM python:3.12-slim
|
|
2
|
+
|
|
3
|
+
LABEL org.opencontainers.image.title="AXEL Network Server"
|
|
4
|
+
LABEL org.opencontainers.image.description="AXEL Agent eXchange Language — multi-LLM network hub"
|
|
5
|
+
LABEL org.opencontainers.image.source="https://github.com/sectorx/axel-protocol"
|
|
6
|
+
LABEL org.opencontainers.image.licenses="MIT"
|
|
7
|
+
|
|
8
|
+
# ── System deps ───────────────────────────────────────────────────
|
|
9
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
10
|
+
curl \
|
|
11
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
12
|
+
|
|
13
|
+
# ── App user (non-root) ───────────────────────────────────────────
|
|
14
|
+
RUN useradd --create-home --shell /bin/bash axel
|
|
15
|
+
WORKDIR /app
|
|
16
|
+
RUN chown axel:axel /app
|
|
17
|
+
|
|
18
|
+
# ── Python deps ───────────────────────────────────────────────────
|
|
19
|
+
COPY pyproject.toml ./
|
|
20
|
+
# Install only the server core; adapters are optional at runtime
|
|
21
|
+
RUN pip install --no-cache-dir "fastapi>=0.110.0" "uvicorn[standard]>=0.29.0" \
|
|
22
|
+
&& pip install --no-cache-dir "anthropic>=0.25.0" "openai>=1.20.0" || true
|
|
23
|
+
|
|
24
|
+
# ── App source ────────────────────────────────────────────────────
|
|
25
|
+
COPY axel/ ./axel/
|
|
26
|
+
|
|
27
|
+
# ── Memory persistence directory ─────────────────────────────────
|
|
28
|
+
RUN mkdir -p /data && chown axel:axel /data
|
|
29
|
+
VOLUME ["/data"]
|
|
30
|
+
|
|
31
|
+
USER axel
|
|
32
|
+
|
|
33
|
+
# ── Runtime ───────────────────────────────────────────────────────
|
|
34
|
+
ENV AXEL_HOST=0.0.0.0
|
|
35
|
+
ENV AXEL_PORT=7331
|
|
36
|
+
ENV AXEL_LOG_LEVEL=info
|
|
37
|
+
ENV AXEL_MEMORY_PATH=/data/memory.json
|
|
38
|
+
|
|
39
|
+
EXPOSE 7331
|
|
40
|
+
|
|
41
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
42
|
+
CMD curl -f http://localhost:7331/status || exit 1
|
|
43
|
+
|
|
44
|
+
CMD ["python", "-m", "axel.server"]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Sector X
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|