agentomatic 0.1.1__tar.gz → 0.2.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.
- {agentomatic-0.1.1 → agentomatic-0.2.0}/CHANGELOG.md +22 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/PKG-INFO +1 -1
- agentomatic-0.2.0/docs/guide/platform-features.md +339 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/guide/prompts.md +5 -4
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/guide/storage.md +10 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/index.md +15 -15
- {agentomatic-0.1.1 → agentomatic-0.2.0}/mkdocs.yml +1 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/pyproject.toml +2 -1
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/_version.py +1 -1
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/core/platform.py +8 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/core/registry.py +3 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/core/router_factory.py +300 -4
- agentomatic-0.2.0/src/agentomatic/providers/llm.py +194 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/storage/__init__.py +6 -2
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/storage/base.py +91 -0
- agentomatic-0.2.0/src/agentomatic/storage/checkpointer.py +230 -0
- agentomatic-0.2.0/src/agentomatic/storage/memory.py +329 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/storage/models.py +54 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/storage/sqlalchemy.py +239 -1
- {agentomatic-0.1.1 → agentomatic-0.2.0}/tests/test_agentomatic.py +191 -1
- {agentomatic-0.1.1 → agentomatic-0.2.0}/tests/test_integration.py +54 -5
- agentomatic-0.2.0/tests/test_platform_features.py +622 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/uv.lock +1 -1
- agentomatic-0.1.1/src/agentomatic/providers/llm.py +0 -116
- agentomatic-0.1.1/src/agentomatic/storage/memory.py +0 -167
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/config.toml +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/ar-SA.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/bn.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/da-DK.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/de-DE.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/el-GR.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/en-US.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/es.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/fr-FR.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/gu.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/he-IL.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/hi.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/it.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/ja.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/kn.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/ko.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/ml.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/mr.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/nl.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/pt-PT.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/ta.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/te.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/zh-CN.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.chainlit/translations/zh-TW.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.dockerignore +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.env.example +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.github/FUNDING.yml +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.github/workflows/ci.yml +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.github/workflows/docs.yml +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.github/workflows/manual-docs.yml +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.github/workflows/manual-pypi.yml +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.github/workflows/pr-checks.yml +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.github/workflows/release.yml +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.gitignore +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.pre-commit-config.yaml +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/.vscode-upload.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/CONTRIBUTING.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/Dockerfile +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/Dockerfile.distroless +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/LICENSE +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/Makefile +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/README.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/TODO.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/assets/logo.png +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docker-compose.yml +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/FRONTEND_API_GUIDE.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/architecture/api-reference.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/architecture/overview.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/assets/architecture_diagram.png +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/assets/logo.png +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/assets/optimization_flow.png +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/changelog.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/cli/commands.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/contributing.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/getting-started/first-agent.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/getting-started/installation.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/getting-started/quickstart.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/guide/agent-structure.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/guide/configuration.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/guide/debug-ui.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/guide/middleware.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/guide/optimization.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/guide/schemas.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/guide/telemetry.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/docs/guide/templates.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/examples/full_agent/README.md +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/examples/full_agent/agents/weather/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/examples/full_agent/agents/weather/api.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/examples/full_agent/agents/weather/config.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/examples/full_agent/agents/weather/graph.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/examples/full_agent/agents/weather/langgraph.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/examples/full_agent/agents/weather/nodes.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/examples/full_agent/agents/weather/prompts.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/examples/full_agent/agents/weather/schemas.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/examples/full_agent/agents/weather/tools.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/examples/full_agent/main.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/examples/hello_agent/agents/hello/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/examples/hello_agent/agents/hello/graph.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/examples/hello_agent/agents/hello/nodes.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/examples/hello_agent/main.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/cli/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/cli/commands.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/cli/templates.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/config/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/config/defaults.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/config/settings.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/core/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/core/lifespan.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/core/manifest.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/core/state.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/middleware/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/middleware/auth.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/middleware/feedback.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/middleware/logging.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/middleware/metrics.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/middleware/rate_limit.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/observability/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/observability/concurrency.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/observability/metrics.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/observability/telemetry.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/optimize/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/optimize/dataset.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/optimize/loop.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/optimize/metrics.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/optimize/optimizer.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/optimize/report.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/optimize/runner.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/optimize/strategies.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/optimize/synthesizer.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/prompts/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/prompts/manager.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/protocols/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/protocols/decorators.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/providers/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/providers/embeddings.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/py.typed +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/ui/.chainlit/config.toml +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/ui/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agentomatic/ui/chat.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agents/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agents/alpha/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agents/alpha/agent.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agents/alpha/api.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agents/alpha/config.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agents/alpha/prompts.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agents/alpha/schemas.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agents/alpha/state.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agents/beta/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agents/beta/agent.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agents/beta/api.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agents/beta/config.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agents/beta/prompts.json +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agents/beta/schemas.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/agents/beta/state.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/app/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/app/api.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/app/dependencies.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/app/main.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/app/settings.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/common/__init__.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/common/agent_state.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/common/api_decorators.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/common/base_agent.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/common/llm_factory.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/common/prompt_manager.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/src/common/utilities.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/tests/test_cli.py +0 -0
- {agentomatic-0.1.1 → agentomatic-0.2.0}/tests/test_optimize.py +0 -0
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## v0.2.0 (2026-06-14)
|
|
5
|
+
|
|
6
|
+
### Documentation
|
|
7
|
+
|
|
8
|
+
- Add telemetry and feedback correlation notes for A/B testing
|
|
9
|
+
([`2c27a86`](https://github.com/UnicoLab/agentomatic/commit/2c27a86ac83b44a022e5d002d88316953f01ab35))
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
- Implement advanced platform features (HITL, checkpointer, structured output, fork, A/B routing,
|
|
14
|
+
fallbacks, hooks) and update documentation
|
|
15
|
+
([`c1a55c3`](https://github.com/UnicoLab/agentomatic/commit/c1a55c39b1efd24084f1453946df27a830d3d7ec))
|
|
16
|
+
|
|
17
|
+
- Increase core test coverage over 85% and enhance homepage aesthetics
|
|
18
|
+
([`98f28f5`](https://github.com/UnicoLab/agentomatic/commit/98f28f56308b7540d642149aa2a7edc20b2eeafb))
|
|
19
|
+
|
|
20
|
+
### Testing
|
|
21
|
+
|
|
22
|
+
- Enhance unit test coverage for sqlalchemy store, sync checkpointers, and structured fallbacks
|
|
23
|
+
([`91ab042`](https://github.com/UnicoLab/agentomatic/commit/91ab04254a623fb4fbd108303265ad8d4b3aeba5))
|
|
24
|
+
|
|
25
|
+
|
|
4
26
|
## v0.1.1 (2026-06-13)
|
|
5
27
|
|
|
6
28
|
### Bug Fixes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentomatic
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Drop agents, not code — zero-code multi-agent API platform framework
|
|
5
5
|
Project-URL: Homepage, https://github.com/UnicoLab/agentomatic
|
|
6
6
|
Project-URL: Documentation, https://unicolab.github.io/agentomatic
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
# Advanced Platform Features
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
<img src="../assets/logo.png" width="200" alt="agentomatic logo">
|
|
5
|
+
<h3>Enterprise-Grade Orchestration & Core Capabilities</h3>
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
Agentomatic provides a suite of advanced platform capabilities designed to make multi-agent systems production-ready. These features solve common real-world challenges around human-in-the-loop validation, schema enforcement, prompt routing, checkpointer persistence, and service resilience.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 🚦 1. Human-in-the-Loop (HITL) Protocol
|
|
15
|
+
|
|
16
|
+
In complex multi-agent architectures, agents often require human validation before executing sensitive actions (e.g., executing a transaction, sending an email, or performing a destructive write).
|
|
17
|
+
|
|
18
|
+
Agentomatic provides a built-in suspension/resume mechanism that allows nodes or graphs to halt execution, serialize their state snapshots to the storage backend, and resume or abort dynamically when approved/rejected via HTTP.
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
┌──────────────────────┐
|
|
22
|
+
│ Agent Execution │
|
|
23
|
+
└──────────┬───────────┘
|
|
24
|
+
│
|
|
25
|
+
Node raises AgentSuspendedException
|
|
26
|
+
│
|
|
27
|
+
▼
|
|
28
|
+
┌──────────────────────┐
|
|
29
|
+
│ Serializes state snapshot │
|
|
30
|
+
│ Saves to database │
|
|
31
|
+
│ Returns HTTP 202 │
|
|
32
|
+
└──────────────────────┘
|
|
33
|
+
│
|
|
34
|
+
┌───────────┴───────────┐
|
|
35
|
+
▼ ▼
|
|
36
|
+
POST /approve POST /reject
|
|
37
|
+
│ │
|
|
38
|
+
Merges human context Deletes snapshot
|
|
39
|
+
Resumes execution Aborts execution
|
|
40
|
+
│ │
|
|
41
|
+
▼ ▼
|
|
42
|
+
┌──────────────────┐ ┌──────────────────┐
|
|
43
|
+
│ Completes graph│ │ Returns 200 OK │
|
|
44
|
+
└──────────────────┘ └──────────────────┘
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Suspending Execution
|
|
48
|
+
|
|
49
|
+
To suspend execution, raise `AgentSuspendedException` from anywhere inside your node function or LangGraph node:
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from agentomatic.core.router_factory import AgentSuspendedException
|
|
53
|
+
|
|
54
|
+
async def financial_transfer_node(state: dict):
|
|
55
|
+
metadata = state.get("metadata") or {}
|
|
56
|
+
|
|
57
|
+
# Check if we already have approval
|
|
58
|
+
if metadata.get("hitl_approved"):
|
|
59
|
+
return {
|
|
60
|
+
"response": f"Successfully transferred ${state['amount']}",
|
|
61
|
+
"metadata": metadata
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
# Otherwise, suspend and wait for human confirmation
|
|
65
|
+
raise AgentSuspendedException(
|
|
66
|
+
approval_id=f"tx_{state['transaction_id']}",
|
|
67
|
+
node_name="financial_transfer_node",
|
|
68
|
+
state_snapshot=state,
|
|
69
|
+
message="Transaction requires human approval."
|
|
70
|
+
)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
When this exception is thrown:
|
|
74
|
+
1. Agentomatic intercepts the execution.
|
|
75
|
+
2. The current `state_snapshot` is stored in the persistent database under `SuspendedStateModel`.
|
|
76
|
+
3. The API immediately returns a `202 Accepted` status code with the approval details.
|
|
77
|
+
|
|
78
|
+
**Response payload:**
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"detail": {
|
|
82
|
+
"status": "suspended",
|
|
83
|
+
"approval_id": "tx_984712",
|
|
84
|
+
"node_name": "financial_transfer_node",
|
|
85
|
+
"message": "Transaction requires human approval."
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### REST Endpoints for Approvals
|
|
91
|
+
|
|
92
|
+
Each registered agent automatically exposes three endpoints to manage suspended states:
|
|
93
|
+
|
|
94
|
+
#### A. List Pending Approvals
|
|
95
|
+
Retrieve all currently suspended states for a specific thread.
|
|
96
|
+
|
|
97
|
+
* **Method:** `GET`
|
|
98
|
+
* **Path:** `/api/v1/{agent_slug}/threads/{thread_id}/pending`
|
|
99
|
+
* **Response:**
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"thread_id": "thread_abc123",
|
|
103
|
+
"count": 1,
|
|
104
|
+
"pending": [
|
|
105
|
+
{
|
|
106
|
+
"id": "tx_984712",
|
|
107
|
+
"node_name": "financial_transfer_node",
|
|
108
|
+
"state_snapshot": { ... },
|
|
109
|
+
"created_at": "2026-06-13T22:50:34"
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### B. Approve and Resume Execution
|
|
116
|
+
Approve the suspension, optionally merge new parameters (e.g., corrections or decisions), and resume the agent's execution from that exact step.
|
|
117
|
+
|
|
118
|
+
* **Method:** `POST`
|
|
119
|
+
* **Path:** `/api/v1/{agent_slug}/threads/{thread_id}/approve`
|
|
120
|
+
* **Payload:**
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"approval_id": "tx_984712",
|
|
124
|
+
"context": {
|
|
125
|
+
"approved_limit": 500
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
* **Behavior:** Deletes the pending suspended snapshot, merges the request's `context` into the state, marks `state.metadata.hitl_approved = True`, and resumes the graph execution synchronously. It returns the final agent execution output.
|
|
130
|
+
|
|
131
|
+
#### C. Reject and Abort Execution
|
|
132
|
+
Reject the transaction and discard the execution context.
|
|
133
|
+
|
|
134
|
+
* **Method:** `POST`
|
|
135
|
+
* **Path:** `/api/v1/{agent_slug}/threads/{thread_id}/reject`
|
|
136
|
+
* **Payload:**
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"approval_id": "tx_984712",
|
|
140
|
+
"reason": "Risk score too high"
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
* **Response:**
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"status": "rejected",
|
|
147
|
+
"approval_id": "tx_984712",
|
|
148
|
+
"reason": "Risk score too high"
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## 💾 2. LangGraph Checkpointer (`AgentomaticCheckpointer`)
|
|
155
|
+
|
|
156
|
+
If you are building your agents using **LangGraph**, you need a checkpoint saver to persist the graph's memory across invocations. Agentomatic provides a native adapter: `AgentomaticCheckpointer`.
|
|
157
|
+
|
|
158
|
+
This checkpointer implements LangGraph's `BaseCheckpointSaver` and delegates storage operations directly to your configured Agentomatic `BaseStore` (e.g., `SQLAlchemyStore` or `MemoryStore`). This ensures that thread states, checkpoint namespaces, and historical tuples are stored consistently without needing a separate database.
|
|
159
|
+
|
|
160
|
+
### Usage Example
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
from langgraph.graph import StateGraph
|
|
164
|
+
from agentomatic.storage import SQLAlchemyStore
|
|
165
|
+
from agentomatic.storage.checkpointer import AgentomaticCheckpointer
|
|
166
|
+
|
|
167
|
+
# 1. Setup your database store
|
|
168
|
+
store = SQLAlchemyStore("postgresql+asyncpg://postgres:secret@localhost:5432/agent_db")
|
|
169
|
+
|
|
170
|
+
# 2. Wrap it with the LangGraph checkpointer adapter
|
|
171
|
+
checkpointer = AgentomaticCheckpointer(store)
|
|
172
|
+
|
|
173
|
+
# 3. Create and compile your LangGraph with the checkpointer
|
|
174
|
+
builder = StateGraph(MyStateClass)
|
|
175
|
+
# ... build graph nodes ...
|
|
176
|
+
|
|
177
|
+
graph = builder.compile(checkpointer=checkpointer)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
All LangGraph checkpoints are automatically persisted in your database and can be fetched or updated using the standard LangGraph runtime config.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## 🎯 3. Structured Output Enforcer
|
|
185
|
+
|
|
186
|
+
Ensuring that LLM outputs strictly match validation schemas is critical for reliable API integration. Agentomatic makes structured output enforcement seamless:
|
|
187
|
+
|
|
188
|
+
1. **Auto-bind Schemas**: Under the hood, Agentomatic leverages LangChain's `.with_structured_output()` to bind Pydantic schemas directly to the LLM runtime.
|
|
189
|
+
2. **Fallback Parser**: If the provider or mock model does not support native schema enforcement (e.g., mock/fake models in test environments), Agentomatic automatically intercepts the output and applies a robust parsing and default-fallback generator wrapper.
|
|
190
|
+
|
|
191
|
+
### Factory Method
|
|
192
|
+
|
|
193
|
+
Use `get_structured_llm` to create a model bound to a Pydantic schema:
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
from pydantic import BaseModel, Field
|
|
197
|
+
from agentomatic.providers.llm import get_structured_llm
|
|
198
|
+
|
|
199
|
+
class TranslationOutput(BaseModel):
|
|
200
|
+
detected_language: str
|
|
201
|
+
translated_text: str
|
|
202
|
+
confidence: float = Field(default=0.0)
|
|
203
|
+
|
|
204
|
+
# Build an LLM instance that returns parsed instances of TranslationOutput
|
|
205
|
+
structured_model = get_structured_llm(
|
|
206
|
+
response_model=TranslationOutput,
|
|
207
|
+
provider="openai",
|
|
208
|
+
model="gpt-4o",
|
|
209
|
+
temperature=0.0
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
result = structured_model.invoke("Translate 'Bonjour tout le monde' to English")
|
|
213
|
+
# 'result' is guaranteed to be a TranslationOutput object
|
|
214
|
+
print(result.translated_text) # "Hello everyone"
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## 🗃️ 4. Thread Forking & Cloning
|
|
220
|
+
|
|
221
|
+
Debugging agent failures or performing A/B evaluation of system prompt prompts requires the ability to fork history. Agentomatic supports **Thread Forking** at the API and database levels.
|
|
222
|
+
|
|
223
|
+
You can clone a parent thread starting at a specific message index. This creates a brand new thread containing a copy of all messages up to and including that index, allowing subsequent interactions to diverge without altering the parent thread's history.
|
|
224
|
+
|
|
225
|
+
* **Method:** `POST`
|
|
226
|
+
* **Path:** `/api/v1/{agent_slug}/threads/{thread_id}/fork`
|
|
227
|
+
* **Payload:**
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"message_index": 2,
|
|
231
|
+
"new_thread_id": "fork_thread_99",
|
|
232
|
+
"title": "A/B Test Variant B"
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
* **Response:** Returns the new thread dictionary:
|
|
236
|
+
```json
|
|
237
|
+
{
|
|
238
|
+
"id": "fork_thread_99",
|
|
239
|
+
"user_id": "user_id_12",
|
|
240
|
+
"agent_name": "support_agent",
|
|
241
|
+
"title": "A/B Test Variant B",
|
|
242
|
+
"message_count": 3,
|
|
243
|
+
"metadata": {}
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## 📊 5. A/B Test Prompt Router
|
|
250
|
+
|
|
251
|
+
Agentomatic enables you to easily conduct prompt version testing in production. You can configure routing splits between different system prompts directly inside your agent configuration.
|
|
252
|
+
|
|
253
|
+
### Configuration
|
|
254
|
+
|
|
255
|
+
Add `prompt_ab_tests` with fractional weights inside your agent's config settings:
|
|
256
|
+
|
|
257
|
+
```json
|
|
258
|
+
{
|
|
259
|
+
"prompt_ab_tests": {
|
|
260
|
+
"v1": 0.7,
|
|
261
|
+
"v2": 0.3
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Execution Flow
|
|
267
|
+
|
|
268
|
+
1. When a client invokes the agent without specifying a `prompt_version` (or when set to `"v1"`), Agentomatic performs a **weighted random choice** based on the configured split (in the example above: 70% traffic to `v1`, 30% traffic to `v2`).
|
|
269
|
+
2. The chosen version is automatically stored in the invocation state under `state["prompt_version"]`.
|
|
270
|
+
3. Your agent nodes can read `prompt_version` from the state to load the correct prompt template.
|
|
271
|
+
4. The chosen version is returned in the response metadata (`metadata.prompt_version`) so that you can trace and analyze performance.
|
|
272
|
+
|
|
273
|
+
### Telemetry & Feedback Correlation
|
|
274
|
+
|
|
275
|
+
To measure the performance and quality of different prompt variants:
|
|
276
|
+
1. **Response Tracking**: Read `metadata.prompt_version` from the `/invoke` or `/chat` JSON response payload.
|
|
277
|
+
2. **Feedback Logging**: When calling the `POST /api/v1/{agent}/feedback` endpoint, pass the active prompt version in the request metadata payload:
|
|
278
|
+
```json
|
|
279
|
+
{
|
|
280
|
+
"thread_id": "thread_123",
|
|
281
|
+
"rating": 5,
|
|
282
|
+
"comment": "Highly accurate answer!",
|
|
283
|
+
"metadata": {
|
|
284
|
+
"prompt_version": "v2"
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
This associates ratings and comments directly with each version, allowing you to run analytical breakdowns of user satisfaction metrics per prompt variant.
|
|
289
|
+
|
|
290
|
+
> [!NOTE]
|
|
291
|
+
> Clients can explicitly override the A/B router by passing a specific `prompt_version` parameter in the invoke request (e.g. `{"prompt_version": "v2"}`).
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## 🛡️ 6. LLM Failover & Fallbacks
|
|
296
|
+
|
|
297
|
+
LLM APIs can suffer from outages, rate limiting (HTTP 429), or transient network errors. To ensure high availability, Agentomatic lets you define chainable fallback providers.
|
|
298
|
+
|
|
299
|
+
### Configuration
|
|
300
|
+
|
|
301
|
+
Pass a list of provider slugs in the `fallbacks` parameter of `get_llm()`:
|
|
302
|
+
|
|
303
|
+
```python
|
|
304
|
+
from agentomatic.providers.llm import get_llm
|
|
305
|
+
|
|
306
|
+
llm = get_llm(
|
|
307
|
+
provider="openai",
|
|
308
|
+
model="gpt-4",
|
|
309
|
+
fallbacks=["azure", "ollama"]
|
|
310
|
+
)
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
If the primary provider (`openai`) raises an exception during execution, LangChain's fallback mechanism automatically routes the request to the next available backup in the list (`azure`, then `ollama`), shielding clients from upstream downtime.
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## 🔌 7. State-Level Hook Middleware (Interceptors)
|
|
318
|
+
|
|
319
|
+
For custom telemetry, audit logging, or real-time security scanning, you can register **state-level node hooks**. These are run instantly before and after every agent node invocation.
|
|
320
|
+
|
|
321
|
+
```python
|
|
322
|
+
from agentomatic import AgentPlatform
|
|
323
|
+
|
|
324
|
+
platform = AgentPlatform.from_folder("agents/")
|
|
325
|
+
|
|
326
|
+
# 1. Register a before-node interceptor
|
|
327
|
+
def audit_input_hook(agent_name: str, state: dict):
|
|
328
|
+
print(f"[Hook] Agent '{agent_name}' is about to run. Query: {state.get('current_query')}")
|
|
329
|
+
# You can inspect or modify the state inline before execution starts
|
|
330
|
+
state["metadata"]["audit_logged"] = True
|
|
331
|
+
|
|
332
|
+
platform.register_before_node_hook(audit_input_hook)
|
|
333
|
+
|
|
334
|
+
# 2. Register an after-node interceptor
|
|
335
|
+
def audit_output_hook(agent_name: str, result: dict):
|
|
336
|
+
print(f"[Hook] Agent '{agent_name}' completed. Response snippet: {result.get('response')[:30]}")
|
|
337
|
+
|
|
338
|
+
platform.register_after_node_hook(audit_output_hook)
|
|
339
|
+
```
|
|
@@ -99,8 +99,7 @@ If you write a custom router using `api.py` and want to load prompt templates dy
|
|
|
99
99
|
|
|
100
100
|
```python
|
|
101
101
|
from fastapi import APIRouter
|
|
102
|
-
from agentomatic import APIResponse, handle_api_errors
|
|
103
|
-
from rac.agents._registry import get_registry
|
|
102
|
+
from agentomatic import APIResponse, handle_api_errors, AgentRegistry
|
|
104
103
|
|
|
105
104
|
router = APIRouter()
|
|
106
105
|
|
|
@@ -108,8 +107,10 @@ router = APIRouter()
|
|
|
108
107
|
@handle_api_errors
|
|
109
108
|
async def custom_chat(query: str) -> APIResponse:
|
|
110
109
|
# Retrieve the agent instance from the registry
|
|
111
|
-
agent =
|
|
112
|
-
|
|
110
|
+
agent = AgentRegistry().get("my_agent")
|
|
111
|
+
if not agent:
|
|
112
|
+
return APIResponse(success=False, message="Agent not found")
|
|
113
|
+
|
|
113
114
|
# Format user prompt
|
|
114
115
|
user_prompt = agent.prompt_manager.format_prompt(
|
|
115
116
|
version=agent.config.prompt_version,
|
|
@@ -192,3 +192,13 @@ Every storage adapter implements the following async interface methods:
|
|
|
192
192
|
| `async def get_messages(id) -> list[dict]` | **Required** | Fetch chronological chat histories |
|
|
193
193
|
| `async def add_feedback(...) -> dict` | Optional | Save user scores and comment metrics |
|
|
194
194
|
| `async def list_feedback(...) -> list[dict]` | Optional | Search feedback records |
|
|
195
|
+
| `async def save_suspended_state(...) -> dict` | Optional | Save execution state for human approval |
|
|
196
|
+
| `async def get_suspended_state(id) -> dict \| None` | Optional | Retrieve a suspended state |
|
|
197
|
+
| `async def list_suspended_states(...) -> list[dict]` | Optional | List all pending suspended states |
|
|
198
|
+
| `async def delete_suspended_state(id) -> bool` | Optional | Delete suspended state on completion |
|
|
199
|
+
| `async def fork_thread(...) -> dict \| None` | Optional | Fork a conversation history up to index |
|
|
200
|
+
| `async def save_checkpoint(...) -> None` | Optional | Save a LangGraph checkpoint state |
|
|
201
|
+
| `async def get_checkpoint(...) -> dict \| None` | Optional | Retrieve a LangGraph checkpoint state |
|
|
202
|
+
| `async def list_checkpoints(...) -> list[dict]` | Optional | List checkpoints for a thread namespace |
|
|
203
|
+
|
|
204
|
+
> 🚦 *For details on how checkpointer, thread forking, and human-in-the-loop suspension integrate with these storage methods, see the [Advanced Platform Features Guide](platform-features.md).*
|
|
@@ -10,20 +10,20 @@ hide:
|
|
|
10
10
|
<img src="assets/logo.png" width="300" alt="agentomatic logo">
|
|
11
11
|
</p>
|
|
12
12
|
|
|
13
|
-
<h3>Drop agents, not code.
|
|
13
|
+
<h3>Drop agents, not code. :octicons-zap-24:</h3>
|
|
14
14
|
<p><b>The zero-code multi-agent API platform framework.</b> Turn any agent script or graph into a secure, resilient, enterprise-grade microservice with auto-discovery, SSE streaming, thread persistence, and prompt optimization — in 3 lines of code.</p>
|
|
15
15
|
|
|
16
16
|
<p>
|
|
17
17
|
<a href="https://pypi.org/project/agentomatic/"><img src="https://img.shields.io/pypi/v/agentomatic.svg" alt="PyPI version"></a>
|
|
18
18
|
<img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+">
|
|
19
19
|
<img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License: MIT">
|
|
20
|
-
<img src="https://img.shields.io/badge/tests-
|
|
20
|
+
<img src="https://img.shields.io/badge/tests-175%20passing-brightgreen.svg" alt="Tests passing">
|
|
21
21
|
</p>
|
|
22
22
|
</div>
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
26
|
-
##
|
|
26
|
+
## :octicons-zap-24: What is Agentomatic?
|
|
27
27
|
|
|
28
28
|
**Agentomatic** acts as a production-ready application server for AI agents. Whether you write raw Python functions, build complex multi-agent orchestrations with **LangGraph**, or chain tools together with **LangChain**, Agentomatic auto-discovers your code and mounts a complete FastAPI application with standard REST routes, server-sent events (SSE) streaming, database adapters, telemetry, and rate limiting.
|
|
29
29
|
|
|
@@ -41,41 +41,41 @@ Run with `uvicorn main:app --reload` and visit `/docs` for a fully documented Op
|
|
|
41
41
|
|
|
42
42
|
---
|
|
43
43
|
|
|
44
|
-
##
|
|
44
|
+
## :material-sitemap: Platform Architecture
|
|
45
45
|
|
|
46
|
-
Agentomatic's core principle is **Convention over Configuration**. By dividing agents into isolated directories containing a manifest, configuration, and
|
|
46
|
+
Agentomatic's core principle is **Convention over Configuration**. By dividing agents into isolated directories containing a manifest, configuration, and an execution graph, the framework automatically maps directory files to API endpoints, database adapters, and prompt templates.
|
|
47
47
|
|
|
48
48
|

|
|
49
49
|
|
|
50
50
|
---
|
|
51
51
|
|
|
52
|
-
##
|
|
52
|
+
## :octicons-star-fill-24: Key Features
|
|
53
53
|
|
|
54
|
-
###
|
|
54
|
+
### :material-flash: 1. Auto-Discovery & Hot Reloading
|
|
55
55
|
Drop a directory containing an `__init__.py` file (which exports an `AgentManifest` and execution function) into your `agents/` folder. Agentomatic automatically spins up a custom FastAPI router, parses your input/output schemas, and mounts a complete suite of **12+ REST endpoints** for that specific agent.
|
|
56
56
|
|
|
57
|
-
###
|
|
57
|
+
### :material-waves: 2. Synchronous & SSE Streaming
|
|
58
58
|
Standardize how clients talk to your agents. Every agent gets a synchronous `/invoke` endpoint and an asynchronous `/invoke/stream` Server-Sent Events (SSE) streaming endpoint that streams intermediate agent thought steps, tool calls, and final answers in real-time.
|
|
59
59
|
|
|
60
|
-
###
|
|
60
|
+
### :material-database: 3. Session-Aware Chat & Persistence
|
|
61
61
|
The `/chat` endpoint manages full context history automatically. By passing a `thread_id`, Agentomatic reads the conversation log, formats it as history, and executes your agent. Swappable database adapters (**MemoryStore**, **SQLAlchemyStore**) let you persist user messages to PostgreSQL, MySQL, or SQLite out of the box.
|
|
62
62
|
|
|
63
|
-
###
|
|
63
|
+
### :material-shield-key: 4. Enterprise-Grade Middleware
|
|
64
64
|
Keep your agents safe and monitored. Toggle middleware filters globally or per-agent:
|
|
65
65
|
- **API Key Auth**: Secured endpoints with customizable key authorization.
|
|
66
66
|
- **Token Bucket Rate Limiting**: Prevent abuse by limiting queries per IP/User.
|
|
67
67
|
- **Prometheus Metrics**: Monitor latency, request counts, and active connections at `/metrics`.
|
|
68
68
|
- **Structured Logging**: Context-scoped loguru logs tracking execution durations and exceptions.
|
|
69
69
|
|
|
70
|
-
###
|
|
70
|
+
### :material-tune-vertical: 5. Prompt Tuning & Optimization (DSPy-inspired)
|
|
71
71
|
Tune prompts like hyper-parameters. Agentomatic includes a prompt optimization module with **7 optimization strategies** (e.g. `iterative_rewrite`, `few_shot_bootstrap`) and **8 evaluation metrics** (answer relevancy, faithfulness, toxic speech check, etc.). Generate synthetic datasets with a single command and track prompt version history with side-by-side HTML reports.
|
|
72
72
|
|
|
73
|
-
###
|
|
73
|
+
### :material-palette: 6. ChatGPT-like Debug UI
|
|
74
74
|
No frontend development required. Run `agentomatic run --with-ui` to launch a built-in, production-quality **Chainlit** chat interface where you can test agents, select prompt versions, inspect step-by-step tool invocations, and submit feedback ratings.
|
|
75
75
|
|
|
76
76
|
---
|
|
77
77
|
|
|
78
|
-
##
|
|
78
|
+
## :material-swap-horizontal: How does it compare?
|
|
79
79
|
|
|
80
80
|
| Feature | Raw FastAPI + LangChain | Agentomatic Platform |
|
|
81
81
|
| :--- | :--- | :--- |
|
|
@@ -88,7 +88,7 @@ No frontend development required. Run `agentomatic run --with-ui` to launch a bu
|
|
|
88
88
|
|
|
89
89
|
---
|
|
90
90
|
|
|
91
|
-
##
|
|
91
|
+
## :material-download: Quick Installation
|
|
92
92
|
|
|
93
93
|
Install Agentomatic and all its production components (including optimizer and web UI) using `pip` or `uv`:
|
|
94
94
|
|
|
@@ -102,7 +102,7 @@ uv add agentomatic --extra all
|
|
|
102
102
|
|
|
103
103
|
---
|
|
104
104
|
|
|
105
|
-
##
|
|
105
|
+
## :material-play: Create Your First Agent
|
|
106
106
|
|
|
107
107
|
Scaffold a basic chatbot and start the local API platform with two terminal commands:
|
|
108
108
|
|
|
@@ -90,6 +90,7 @@ nav:
|
|
|
90
90
|
- Configuration: guide/configuration.md
|
|
91
91
|
- Storage Backends: guide/storage.md
|
|
92
92
|
- Middleware: guide/middleware.md
|
|
93
|
+
- Advanced Platform Features: guide/platform-features.md
|
|
93
94
|
- Prompt Optimization: guide/optimization.md
|
|
94
95
|
- Telemetry & Feedback: guide/telemetry.md
|
|
95
96
|
- Debug UI: guide/debug-ui.md
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "agentomatic"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.2.0"
|
|
4
4
|
description = "Drop agents, not code — zero-code multi-agent API platform framework"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = {text = "MIT"}
|
|
@@ -81,6 +81,7 @@ Changelog = "https://github.com/UnicoLab/agentomatic/blob/main/CHANGELOG.md"
|
|
|
81
81
|
|
|
82
82
|
|
|
83
83
|
|
|
84
|
+
|
|
84
85
|
[dependency-groups]
|
|
85
86
|
dev = [
|
|
86
87
|
"pytest>=8",
|
|
@@ -171,6 +171,14 @@ class AgentPlatform:
|
|
|
171
171
|
"""Set the storage backend."""
|
|
172
172
|
self._store = value
|
|
173
173
|
|
|
174
|
+
def register_before_node_hook(self, hook: Callable[[str, dict[str, Any]], None]) -> None:
|
|
175
|
+
"""Register a hook to execute before any agent node/graph runs."""
|
|
176
|
+
self._registry.before_node_hooks.append(hook)
|
|
177
|
+
|
|
178
|
+
def register_after_node_hook(self, hook: Callable[[str, dict[str, Any]], None]) -> None:
|
|
179
|
+
"""Register a hook to execute after any agent node/graph runs."""
|
|
180
|
+
self._registry.after_node_hooks.append(hook)
|
|
181
|
+
|
|
174
182
|
# ------------------------------------------------------------------
|
|
175
183
|
# Programmatic registration
|
|
176
184
|
# ------------------------------------------------------------------
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import importlib
|
|
6
|
+
from collections.abc import Callable
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
from typing import Any
|
|
8
9
|
|
|
@@ -25,6 +26,8 @@ class AgentRegistry:
|
|
|
25
26
|
|
|
26
27
|
def __init__(self) -> None:
|
|
27
28
|
self._agents: dict[str, RegisteredAgent] = {}
|
|
29
|
+
self.before_node_hooks: list[Callable[[str, dict[str, Any]], None]] = []
|
|
30
|
+
self.after_node_hooks: list[Callable[[str, dict[str, Any]], None]] = []
|
|
28
31
|
|
|
29
32
|
@property
|
|
30
33
|
def count(self) -> int:
|