agentensemble 0.3.0__tar.gz → 0.4.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.
- agentensemble-0.4.0/CHANGELOG.md +73 -0
- agentensemble-0.4.0/LICENSE +21 -0
- {agentensemble-0.3.0 → agentensemble-0.4.0}/MANIFEST.in +2 -2
- {agentensemble-0.3.0/agentensemble.egg-info → agentensemble-0.4.0}/PKG-INFO +155 -40
- agentensemble-0.3.0/PKG-INFO → agentensemble-0.4.0/README.md +129 -73
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/__init__.py +27 -24
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/agents/__init__.py +4 -3
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/agents/base.py +11 -10
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/agents/hybrid_agent.py +27 -23
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/agents/rag_agent.py +19 -19
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/agents/react_agent.py +99 -46
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/agents/stategraph_agent.py +23 -23
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/agents/structured_agent.py +51 -51
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/core/protocol.py +4 -5
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/graph/__init__.py +1 -1
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/graph/workflow.py +12 -9
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/llm/__init__.py +3 -2
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/llm/interface.py +17 -20
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/llm/mistral_provider.py +27 -20
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/memory/__init__.py +1 -1
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/memory/session.py +6 -6
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/memory/sqlite_session.py +5 -5
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/orchestration/__init__.py +2 -3
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/orchestration/debate.py +6 -6
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/orchestration/ensemble.py +37 -56
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/orchestration/pipeline.py +6 -6
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/orchestration/supervisor.py +6 -6
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/orchestration/swarm.py +6 -6
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/planner/planner_agent.py +10 -9
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/router/router_agent.py +12 -10
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/runner.py +16 -15
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/testing/__init__.py +1 -2
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/testing/benchmark.py +12 -13
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/testing/comparison.py +25 -17
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/testing/metrics.py +20 -21
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/tools/__init__.py +4 -4
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/tools/adapters.py +8 -7
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/tools/function_tool.py +6 -6
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/tools/protocol.py +11 -14
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/tools/rag.py +10 -11
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/tools/registry.py +21 -22
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/tools/scraper.py +8 -25
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/tools/search.py +20 -5
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/tools/validator.py +9 -11
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/tracing/__init__.py +7 -1
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/tracing/hooks.py +20 -14
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/utils/__init__.py +1 -2
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/utils/llm.py +6 -8
- agentensemble-0.3.0/README.md → agentensemble-0.4.0/agentensemble.egg-info/PKG-INFO +189 -21
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble.egg-info/SOURCES.txt +3 -1
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble.egg-info/requires.txt +10 -11
- {agentensemble-0.3.0 → agentensemble-0.4.0}/pyproject.toml +45 -33
- {agentensemble-0.3.0 → agentensemble-0.4.0}/tests/test_agents.py +5 -5
- {agentensemble-0.3.0 → agentensemble-0.4.0}/tests/test_comparison.py +1 -1
- {agentensemble-0.3.0 → agentensemble-0.4.0}/tests/test_memory.py +8 -8
- {agentensemble-0.3.0 → agentensemble-0.4.0}/tests/test_orchestration.py +5 -2
- {agentensemble-0.3.0 → agentensemble-0.4.0}/tests/test_react_session.py +6 -6
- agentensemble-0.4.0/tests/test_release.py +98 -0
- {agentensemble-0.3.0 → agentensemble-0.4.0}/tests/test_runner.py +2 -3
- {agentensemble-0.3.0 → agentensemble-0.4.0}/tests/test_tools.py +3 -5
- {agentensemble-0.3.0 → agentensemble-0.4.0}/tests/test_tracing.py +1 -3
- agentensemble-0.3.0/setup.py +0 -15
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/core/__init__.py +0 -0
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/planner/__init__.py +0 -0
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/py.typed +0 -0
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble/router/__init__.py +0 -0
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble.egg-info/dependency_links.txt +0 -0
- {agentensemble-0.3.0 → agentensemble-0.4.0}/agentensemble.egg-info/top_level.txt +0 -0
- {agentensemble-0.3.0 → agentensemble-0.4.0}/setup.cfg +0 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to AgentEnsemble will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.4.0] - 2026-10-31
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- `ReActAgent` can now be constructed without `MISTRAL_API_KEY` (matching `HybridAgent` and
|
|
14
|
+
`RouterAgent`); `run()` / `astream()` raise a clear `RuntimeError` until an LLM is configured.
|
|
15
|
+
Previously the constructor raised `ValueError`, which broke 6 tests and any offline usage.
|
|
16
|
+
- `SearchTool`'s DuckDuckGo fallback works again: `langchain-community` now needs the `ddgs`
|
|
17
|
+
package (the `search` extra previously installed the old `duckduckgo-search`).
|
|
18
|
+
- `SearchTool` creates its backend lazily on first use, so it can be registered in a
|
|
19
|
+
`ToolRegistry` without optional dependencies; a missing backend raises an `ImportError` with
|
|
20
|
+
the `pip install 'agentensemble[search]'` hint. Unknown providers still fail fast.
|
|
21
|
+
- Tool schema type inference uses identity checks (`ann is str`), not equality.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
- `MISTRAL_MODEL` environment variable to choose the default model for `MistralLLMProvider`.
|
|
25
|
+
- `__version__` read from installed package metadata (`importlib.metadata`).
|
|
26
|
+
- GitHub Actions CI (ruff lint + format check, pytest on Python 3.10–3.13).
|
|
27
|
+
- New tests: ReActAgent tool-calling loop with a fake LLM, SearchTool behaviour, version, model
|
|
28
|
+
override (64 tests total).
|
|
29
|
+
- SECURITY.md, CODE_OF_CONDUCT.md, issue/PR templates, Dependabot, CITATION.cff.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
- Requires Python 3.10+ (3.9 is end-of-life); classifiers for 3.10–3.13.
|
|
33
|
+
- Packaging is `pyproject.toml`-only (removed `setup.py` and `requirements.txt`), PEP 639
|
|
34
|
+
`license = "MIT"`, LICENSE and CHANGELOG shipped in the sdist.
|
|
35
|
+
- Dependency floors raised to the versions the code actually needs: `langchain>=1.1`,
|
|
36
|
+
`langchain-core>=1.0`, `langchain-community>=0.3`, `langchain-mistralai>=0.2`. The unused
|
|
37
|
+
direct `langgraph` dependency was dropped (it is still installed transitively by `langchain`).
|
|
38
|
+
- `dev` extra now includes `build` and `twine`; `black` replaced by `ruff format`.
|
|
39
|
+
- Codebase formatted with `ruff format` and modernised type hints (`X | None`).
|
|
40
|
+
|
|
41
|
+
## [0.3.0] - 2026-03-10
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
- Observability (`TraceHooks`, token usage, cost estimation), human-in-the-loop
|
|
45
|
+
(`interrupt_before_tools`), architecture diagram.
|
|
46
|
+
|
|
47
|
+
## [0.2.0] - 2026-03-10
|
|
48
|
+
|
|
49
|
+
### Added
|
|
50
|
+
- `RouterAgent`, `PlannerAgent`, `WorkflowGraph`, tracing.
|
|
51
|
+
|
|
52
|
+
## [0.1.0] - 2025-12-09
|
|
53
|
+
|
|
54
|
+
### Added
|
|
55
|
+
- Initial release
|
|
56
|
+
- ReActAgent implementation
|
|
57
|
+
- StateGraphAgent implementation
|
|
58
|
+
- RAGAgent with fallback strategies
|
|
59
|
+
- HybridAgent with intelligent routing
|
|
60
|
+
- Ensemble orchestration patterns (Supervisor, Swarm, Pipeline)
|
|
61
|
+
- Tool ecosystem (Search, Scraper, RAG, Validator)
|
|
62
|
+
- Tool registry for centralized management
|
|
63
|
+
- Testing framework (AgentComparison, Benchmark, Metrics)
|
|
64
|
+
- Base agent class and state management
|
|
65
|
+
- Comprehensive documentation
|
|
66
|
+
|
|
67
|
+
### Infrastructure
|
|
68
|
+
- Python 3.9+ support
|
|
69
|
+
- pyproject.toml for modern packaging
|
|
70
|
+
- Development dependencies (pytest, black, ruff, mypy)
|
|
71
|
+
- MIT License
|
|
72
|
+
- Contributing guidelines
|
|
73
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Irfan Ali
|
|
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.
|
|
@@ -1,41 +1,47 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentensemble
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Build, orchestrate, trace, and test multi-agent LLM systems in Python: ReAct, RAG, router, planner, workflow graphs, swarms, debates, and pipelines.
|
|
5
5
|
Author-email: Irfan Ali <irfanali29@hotmail.com>
|
|
6
6
|
Maintainer-email: Irfan Ali <irfanali29@hotmail.com>
|
|
7
|
-
License: MIT
|
|
7
|
+
License-Expression: MIT
|
|
8
8
|
Project-URL: Homepage, https://github.com/irfanalidv/AgentEnsemble
|
|
9
9
|
Project-URL: Documentation, https://github.com/irfanalidv/AgentEnsemble#readme
|
|
10
10
|
Project-URL: Repository, https://github.com/irfanalidv/AgentEnsemble
|
|
11
11
|
Project-URL: Issues, https://github.com/irfanalidv/AgentEnsemble/issues
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
Project-URL: Changelog, https://github.com/irfanalidv/AgentEnsemble/blob/main/CHANGELOG.md
|
|
13
|
+
Keywords: ai-agents,multi-agent,multi-agent-systems,agent-orchestration,orchestration,llm,langchain,langgraph,mistral,rag,react-agent,tool-calling,function-calling,agent-testing,agentic-ai,state-graph,workflow,tracing
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
15
|
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: Science/Research
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
15
18
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
16
|
-
Classifier:
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
20
|
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
19
21
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
22
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
23
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
-
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
26
|
+
Classifier: Typing :: Typed
|
|
27
|
+
Requires-Python: >=3.10
|
|
23
28
|
Description-Content-Type: text/markdown
|
|
24
|
-
|
|
25
|
-
Requires-Dist: langchain
|
|
26
|
-
Requires-Dist: langchain-
|
|
27
|
-
Requires-Dist: langchain-
|
|
28
|
-
Requires-Dist:
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Requires-Dist: langchain>=1.1.0
|
|
31
|
+
Requires-Dist: langchain-core>=1.0.0
|
|
32
|
+
Requires-Dist: langchain-community>=0.3.0
|
|
33
|
+
Requires-Dist: langchain-mistralai>=0.2.0
|
|
29
34
|
Requires-Dist: pydantic>=2.0.0
|
|
30
35
|
Requires-Dist: typing-extensions>=4.5.0
|
|
31
36
|
Requires-Dist: python-dotenv>=1.0.0
|
|
32
37
|
Provides-Extra: dev
|
|
33
38
|
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
34
39
|
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
35
|
-
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
36
|
-
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
37
|
-
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
38
40
|
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
41
|
+
Requires-Dist: ruff>=0.6.0; extra == "dev"
|
|
42
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
43
|
+
Requires-Dist: build>=1.0.0; extra == "dev"
|
|
44
|
+
Requires-Dist: twine>=5.0.0; extra == "dev"
|
|
39
45
|
Provides-Extra: observability
|
|
40
46
|
Requires-Dist: langsmith>=0.1.0; extra == "observability"
|
|
41
47
|
Requires-Dist: opentelemetry-api>=1.20.0; extra == "observability"
|
|
@@ -44,23 +50,93 @@ Requires-Dist: chromadb>=0.4.0; extra == "rag"
|
|
|
44
50
|
Requires-Dist: sentence-transformers>=2.2.0; extra == "rag"
|
|
45
51
|
Requires-Dist: langchain-text-splitters>=0.0.1; extra == "rag"
|
|
46
52
|
Requires-Dist: beautifulsoup4>=4.12.0; extra == "rag"
|
|
47
|
-
Requires-Dist: langchain-mistralai>=0.1.0; extra == "rag"
|
|
48
53
|
Provides-Extra: search
|
|
49
|
-
Requires-Dist:
|
|
54
|
+
Requires-Dist: ddgs>=9.0.0; extra == "search"
|
|
50
55
|
Requires-Dist: google-search-results>=2.4.2; extra == "search"
|
|
51
56
|
Provides-Extra: all
|
|
52
|
-
Requires-Dist: agentensemble[
|
|
57
|
+
Requires-Dist: agentensemble[observability,rag,search]; extra == "all"
|
|
58
|
+
Dynamic: license-file
|
|
59
|
+
|
|
60
|
+
<div align="center">
|
|
53
61
|
|
|
54
62
|
# AgentEnsemble
|
|
55
63
|
|
|
56
|
-
**
|
|
64
|
+
**Build, orchestrate, trace, and test multi-agent LLM systems in Python.**
|
|
57
65
|
|
|
58
|
-
|
|
66
|
+
ReAct, RAG, router, planner, workflow graphs, swarms, debates, and pipelines, with sessions,
|
|
67
|
+
tracing, retries, and human-in-the-loop approval built in.
|
|
59
68
|
|
|
60
|
-
[](https://pypi.org/project/agentensemble/)
|
|
70
|
+
[](https://pypi.org/project/agentensemble/)
|
|
71
|
+
[](https://github.com/irfanalidv/AgentEnsemble/actions/workflows/tests.yml)
|
|
63
72
|
[](https://pepy.tech/projects/agentensemble)
|
|
73
|
+
[](https://github.com/irfanalidv/AgentEnsemble/blob/main/LICENSE)
|
|
74
|
+
[](https://github.com/astral-sh/ruff)
|
|
75
|
+
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
AgentEnsemble is a framework for building and orchestrating AI agent systems, designed for clarity,
|
|
81
|
+
extensibility, and production use. It covers similar ground to LangGraph, CrewAI, and AutoGen.
|
|
82
|
+
|
|
83
|
+
## Installation
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pip install agentensemble # core: agents, orchestration, graphs, memory, tracing
|
|
87
|
+
pip install "agentensemble[search]" # + DuckDuckGo / Serper web search for SearchTool
|
|
88
|
+
pip install "agentensemble[rag]" # + Chroma, sentence-transformers, loaders for RAGTool
|
|
89
|
+
pip install "agentensemble[observability]" # + LangSmith / OpenTelemetry
|
|
90
|
+
pip install "agentensemble[all]" # everything above
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Requires Python 3.10+.
|
|
94
|
+
|
|
95
|
+
## Quick start (no API key needed)
|
|
96
|
+
|
|
97
|
+
Graph workflows, state-graph agents, and the planner run without any LLM:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from agentensemble import WorkflowGraph
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def analyze(s):
|
|
104
|
+
return {"context": {**s.get("context", {}), "done": True}, "current_node": "summarize"}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def summarize(s):
|
|
108
|
+
return {"result": f"Summary for: {s['query']}", "current_node": "end"}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
graph = (
|
|
112
|
+
WorkflowGraph(entry="start", exit_nodes=["end"])
|
|
113
|
+
.add_node("start", lambda s: {"current_node": "analyze"})
|
|
114
|
+
.add_node("analyze", analyze)
|
|
115
|
+
.add_node("summarize", summarize)
|
|
116
|
+
.add_edge("start", "analyze")
|
|
117
|
+
.add_edge("analyze", "summarize")
|
|
118
|
+
.add_edge("summarize", "end")
|
|
119
|
+
)
|
|
120
|
+
print(graph.run("What is multi-agent AI?")["result"])
|
|
121
|
+
# Summary for: What is multi-agent AI?
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
LLM-powered agents (`ReActAgent`, `HybridAgent`, `RouterAgent`, `StructuredAgent`) use Mistral by
|
|
125
|
+
default. Set `MISTRAL_API_KEY`, or pass any `LLMProvider` implementation via `llm=...`.
|
|
126
|
+
|
|
127
|
+
## Configuration
|
|
128
|
+
|
|
129
|
+
| Variable | Purpose |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| `MISTRAL_API_KEY` | Required for the default Mistral LLM provider (ReAct, Hybrid, Router, Structured agents). |
|
|
132
|
+
| `MISTRAL_MODEL` | Optional default model for `MistralLLMProvider` (default: `mistral-large-latest`). Use e.g. `mistral-small-latest` if your plan doesn't include the large model. |
|
|
133
|
+
| `SERPER_API_KEY` | Optional. When set, `SearchTool()` uses Serper; otherwise it falls back to DuckDuckGo (needs the `search` extra). |
|
|
134
|
+
|
|
135
|
+
Copy `.env.example` to `.env` and fill in your keys (`KEY=value`, no spaces around `=`); the
|
|
136
|
+
package loads `.env` automatically via `python-dotenv`.
|
|
137
|
+
|
|
138
|
+
Without an API key, LLM agents can still be constructed (and inspected or registered); calling
|
|
139
|
+
`run()` raises a clear `RuntimeError` explaining how to configure an LLM.
|
|
64
140
|
|
|
65
141
|
---
|
|
66
142
|
|
|
@@ -76,7 +152,7 @@ AgentEnsemble is a modern framework for building and orchestrating AI agent syst
|
|
|
76
152
|
## Architecture
|
|
77
153
|
|
|
78
154
|
<p align="center">
|
|
79
|
-
<img src="docs/agentensemble-architecture.png" alt="AgentEnsemble Architecture" width="900"/>
|
|
155
|
+
<img src="https://raw.githubusercontent.com/irfanalidv/AgentEnsemble/main/docs/agentensemble-architecture.png" alt="AgentEnsemble Architecture" width="900"/>
|
|
80
156
|
</p>
|
|
81
157
|
|
|
82
158
|
### Framework layers
|
|
@@ -116,11 +192,11 @@ AgentEnsemble is a modern framework for building and orchestrating AI agent syst
|
|
|
116
192
|
|
|
117
193
|
---
|
|
118
194
|
|
|
119
|
-
##
|
|
195
|
+
## LLM quick start
|
|
120
196
|
|
|
121
197
|
```bash
|
|
122
|
-
pip install agentensemble
|
|
123
|
-
|
|
198
|
+
pip install "agentensemble[search]"
|
|
199
|
+
export MISTRAL_API_KEY=...
|
|
124
200
|
```
|
|
125
201
|
|
|
126
202
|
```python
|
|
@@ -137,7 +213,7 @@ print(result["result"])
|
|
|
137
213
|
|
|
138
214
|
## Examples — Code + Output
|
|
139
215
|
|
|
140
|
-
Each example is runnable. Requires
|
|
216
|
+
Each example is runnable. Requires `MISTRAL_API_KEY` (and the `search` extra for `SearchTool`; `SERPER_API_KEY` is optional). Outputs below are from the author's runs; LLM answers will vary.
|
|
141
217
|
|
|
142
218
|
---
|
|
143
219
|
|
|
@@ -166,10 +242,12 @@ enable machine learning with artificial neural networks.
|
|
|
166
242
|
```python
|
|
167
243
|
from agentensemble import ReActAgent, SearchTool, function_tool
|
|
168
244
|
|
|
245
|
+
|
|
169
246
|
@function_tool(description="Get current weather for a city")
|
|
170
247
|
def get_weather(city: str) -> str:
|
|
171
248
|
return f"Weather in {city}: 72°F, partly cloudy"
|
|
172
249
|
|
|
250
|
+
|
|
173
251
|
agent = ReActAgent(tools=[SearchTool(), get_weather], max_iterations=4)
|
|
174
252
|
result = agent.run("What is the weather in Paris?")
|
|
175
253
|
print(result["result"])
|
|
@@ -282,7 +360,9 @@ researcher = ReActAgent(name="researcher", tools=[SearchTool()], max_iterations=
|
|
|
282
360
|
validator = ReActAgent(name="validator", tools=[SearchTool()], max_iterations=2)
|
|
283
361
|
|
|
284
362
|
router = RouterAgent(agents={"researcher": researcher, "validator": validator})
|
|
285
|
-
ensemble = Ensemble(
|
|
363
|
+
ensemble = Ensemble(
|
|
364
|
+
conductor="supervisor", agents={"researcher": researcher, "validator": validator}, router=router
|
|
365
|
+
)
|
|
286
366
|
result = ensemble.perform("Latest developments in quantum computing")
|
|
287
367
|
for name, r in result["results"].items():
|
|
288
368
|
print(f"Routed to {name}: {r['result'][:120]}...")
|
|
@@ -302,9 +382,11 @@ Routed to researcher: Here are the latest developments in quantum computing:
|
|
|
302
382
|
```python
|
|
303
383
|
from agentensemble import PlannerAgent, StateGraphAgent
|
|
304
384
|
|
|
385
|
+
|
|
305
386
|
def worker(state):
|
|
306
387
|
return {"result": f"Processed: {state.query}"}
|
|
307
388
|
|
|
389
|
+
|
|
308
390
|
executor = StateGraphAgent(name="worker", nodes={"start": worker})
|
|
309
391
|
executor._route = lambda s, c: "end"
|
|
310
392
|
|
|
@@ -329,12 +411,15 @@ Result: Processed: Search for information... --- Processed: Summarize key findin
|
|
|
329
411
|
```python
|
|
330
412
|
from agentensemble import WorkflowGraph
|
|
331
413
|
|
|
414
|
+
|
|
332
415
|
def analyze(s):
|
|
333
416
|
return {"context": {**s.get("context", {}), "done": True}, "current_node": "summarize"}
|
|
334
417
|
|
|
418
|
+
|
|
335
419
|
def summarize(s):
|
|
336
420
|
return {"result": f"Summary for: {s['query']}", "current_node": "end"}
|
|
337
421
|
|
|
422
|
+
|
|
338
423
|
graph = (
|
|
339
424
|
WorkflowGraph(entry="start", exit_nodes=["end"])
|
|
340
425
|
.add_node("start", lambda s: {"current_node": "analyze"})
|
|
@@ -364,8 +449,14 @@ from agentensemble import ReActAgent, Runner, RunConfig, RunHooks, InMemorySessi
|
|
|
364
449
|
session = InMemorySession(session_id="chat-1")
|
|
365
450
|
agent = ReActAgent(name="chatbot", tools=[SearchTool()], session=session, max_iterations=3)
|
|
366
451
|
|
|
367
|
-
|
|
368
|
-
def
|
|
452
|
+
|
|
453
|
+
def on_start(q, _):
|
|
454
|
+
print(f"→ User: {q[:50]}...")
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
def on_end(r):
|
|
458
|
+
print(f"← Agent: {r['result'][:80]}...\n")
|
|
459
|
+
|
|
369
460
|
|
|
370
461
|
config = RunConfig(hooks=RunHooks(on_start=on_start, on_end=on_end))
|
|
371
462
|
|
|
@@ -418,10 +509,12 @@ Events: ['run_start', 'llm_start', 'llm_end', 'tool_start', 'tool_end', 'llm_sta
|
|
|
418
509
|
```python
|
|
419
510
|
from agentensemble import ReActAgent, Runner, RunConfig, function_tool
|
|
420
511
|
|
|
512
|
+
|
|
421
513
|
@function_tool(description="Execute a payment")
|
|
422
514
|
def execute_payment(amount: float, recipient: str) -> str:
|
|
423
515
|
return f"Paid ${amount} to {recipient}"
|
|
424
516
|
|
|
517
|
+
|
|
425
518
|
agent = ReActAgent(tools=[execute_payment], max_iterations=2)
|
|
426
519
|
config = RunConfig(interrupt_before_tools=["execute_payment"])
|
|
427
520
|
|
|
@@ -430,7 +523,9 @@ result = Runner.run(agent, "Pay $50 to Alice", config=config)
|
|
|
430
523
|
if result.get("__interrupted__"):
|
|
431
524
|
print("Paused for approval:", result["pending_tool"])
|
|
432
525
|
# Simulate human approval
|
|
433
|
-
result = Runner.run(
|
|
526
|
+
result = Runner.run(
|
|
527
|
+
agent, "...", config=config, resume=result["run_state"], resume_value="Paid $50 to Alice"
|
|
528
|
+
)
|
|
434
529
|
print(result["result"])
|
|
435
530
|
```
|
|
436
531
|
|
|
@@ -470,11 +565,13 @@ manageable subtasks that can be executed by specialized agents...
|
|
|
470
565
|
from pydantic import BaseModel, Field
|
|
471
566
|
from agentensemble import StructuredAgent
|
|
472
567
|
|
|
568
|
+
|
|
473
569
|
class ProductReview(BaseModel):
|
|
474
570
|
product: str = Field(description="Product name")
|
|
475
571
|
rating: int = Field(description="1-5 stars")
|
|
476
572
|
summary: str = Field(description="Brief summary")
|
|
477
573
|
|
|
574
|
+
|
|
478
575
|
agent = StructuredAgent(response_format=ProductReview)
|
|
479
576
|
result = agent.run("Review: iPhone 15 Pro - 5 stars, excellent camera and battery")
|
|
480
577
|
print(result["structured_response"])
|
|
@@ -491,9 +588,15 @@ ProductReview(product='iPhone 15 Pro', rating=5, summary='Excellent camera and b
|
|
|
491
588
|
|
|
492
589
|
```python
|
|
493
590
|
from agentensemble import (
|
|
494
|
-
ReActAgent,
|
|
495
|
-
|
|
496
|
-
|
|
591
|
+
ReActAgent,
|
|
592
|
+
PlannerAgent,
|
|
593
|
+
StateGraphAgent,
|
|
594
|
+
SwarmOrchestrator,
|
|
595
|
+
DebateOrchestrator,
|
|
596
|
+
Runner,
|
|
597
|
+
RunConfig,
|
|
598
|
+
RunHooks,
|
|
599
|
+
SearchTool,
|
|
497
600
|
)
|
|
498
601
|
|
|
499
602
|
# 1. Executor: ReActAgent with search
|
|
@@ -636,14 +739,26 @@ agentensemble/
|
|
|
636
739
|
|
|
637
740
|
## Documentation
|
|
638
741
|
|
|
639
|
-
- **[Showcase](examples/showcase_all.py)** — Run
|
|
742
|
+
- **[Showcase](examples/showcase_all.py)** — Run the features end to end with real API calls
|
|
743
|
+
- [Changelog](CHANGELOG.md)
|
|
640
744
|
- [Examples](examples/) — `quickstart`, `react_llm`, `swarm`, `pipeline`, `streaming`, `debate`, `rag`, `research_agent`, `graph_workflow`, `runner`, `structured_output`
|
|
641
745
|
- [Roadmap](docs/ROADMAP_2025.md) — Planned improvements
|
|
642
746
|
|
|
643
|
-
> **Note:** Ensure `docs/agentensemble-architecture.png` is committed so the architecture diagram renders on GitHub.
|
|
644
|
-
|
|
645
747
|
---
|
|
646
748
|
|
|
749
|
+
## Contributing
|
|
750
|
+
|
|
751
|
+
Contributions are welcome. See [CONTRIBUTING.md](https://github.com/irfanalidv/AgentEnsemble/blob/main/CONTRIBUTING.md)
|
|
752
|
+
and the [Code of Conduct](https://github.com/irfanalidv/AgentEnsemble/blob/main/CODE_OF_CONDUCT.md).
|
|
753
|
+
|
|
754
|
+
```bash
|
|
755
|
+
git clone https://github.com/irfanalidv/AgentEnsemble.git && cd AgentEnsemble
|
|
756
|
+
pip install -e ".[dev]"
|
|
757
|
+
ruff check . && ruff format --check . && pytest
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
Security issues: please follow [SECURITY.md](https://github.com/irfanalidv/AgentEnsemble/blob/main/SECURITY.md).
|
|
761
|
+
|
|
647
762
|
## License
|
|
648
763
|
|
|
649
|
-
MIT — see [LICENSE](LICENSE).
|
|
764
|
+
MIT — see [LICENSE](https://github.com/irfanalidv/AgentEnsemble/blob/main/LICENSE).
|