agentomatic 0.2.0__tar.gz → 0.3.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.2.0 → agentomatic-0.3.0}/CHANGELOG.md +8 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/PKG-INFO +18 -2
- {agentomatic-0.2.0 → agentomatic-0.3.0}/README.md +17 -1
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/guide/configuration.md +12 -2
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/guide/platform-features.md +350 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/guide/schemas.md +67 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/guide/storage.md +6 -2
- {agentomatic-0.2.0 → agentomatic-0.3.0}/pyproject.toml +2 -1
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/__init__.py +2 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/_version.py +1 -1
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/core/__init__.py +14 -0
- agentomatic-0.3.0/src/agentomatic/core/memory_manager.py +349 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/core/platform.py +15 -6
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/core/router_factory.py +320 -24
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/core/state.py +4 -0
- agentomatic-0.3.0/src/agentomatic/providers/__init__.py +21 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/providers/llm.py +48 -19
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/storage/__init__.py +1 -1
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/storage/base.py +17 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/storage/checkpointer.py +33 -9
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/storage/memory.py +73 -6
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/storage/models.py +14 -1
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/storage/sqlalchemy.py +57 -3
- {agentomatic-0.2.0 → agentomatic-0.3.0}/tests/test_agentomatic.py +1 -1
- agentomatic-0.3.0/tests/test_platform_features.py +1660 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/uv.lock +1 -1
- agentomatic-0.2.0/src/agentomatic/providers/__init__.py +0 -3
- agentomatic-0.2.0/tests/test_platform_features.py +0 -622
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/config.toml +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/ar-SA.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/bn.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/da-DK.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/de-DE.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/el-GR.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/en-US.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/es.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/fr-FR.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/gu.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/he-IL.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/hi.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/it.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/ja.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/kn.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/ko.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/ml.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/mr.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/nl.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/pt-PT.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/ta.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/te.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/zh-CN.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.chainlit/translations/zh-TW.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.dockerignore +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.env.example +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.github/FUNDING.yml +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.github/workflows/ci.yml +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.github/workflows/docs.yml +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.github/workflows/manual-docs.yml +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.github/workflows/manual-pypi.yml +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.github/workflows/pr-checks.yml +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.github/workflows/release.yml +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.gitignore +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.pre-commit-config.yaml +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/.vscode-upload.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/CONTRIBUTING.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/Dockerfile +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/Dockerfile.distroless +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/LICENSE +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/Makefile +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/TODO.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/assets/logo.png +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docker-compose.yml +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/FRONTEND_API_GUIDE.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/architecture/api-reference.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/architecture/overview.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/assets/architecture_diagram.png +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/assets/logo.png +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/assets/optimization_flow.png +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/changelog.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/cli/commands.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/contributing.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/getting-started/first-agent.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/getting-started/installation.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/getting-started/quickstart.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/guide/agent-structure.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/guide/debug-ui.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/guide/middleware.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/guide/optimization.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/guide/prompts.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/guide/telemetry.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/guide/templates.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/docs/index.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/examples/full_agent/README.md +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/examples/full_agent/agents/weather/__init__.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/examples/full_agent/agents/weather/api.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/examples/full_agent/agents/weather/config.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/examples/full_agent/agents/weather/graph.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/examples/full_agent/agents/weather/langgraph.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/examples/full_agent/agents/weather/nodes.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/examples/full_agent/agents/weather/prompts.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/examples/full_agent/agents/weather/schemas.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/examples/full_agent/agents/weather/tools.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/examples/full_agent/main.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/examples/hello_agent/agents/hello/__init__.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/examples/hello_agent/agents/hello/graph.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/examples/hello_agent/agents/hello/nodes.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/examples/hello_agent/main.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/mkdocs.yml +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/__init__.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/cli/__init__.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/cli/commands.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/cli/templates.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/config/__init__.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/config/defaults.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/config/settings.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/core/lifespan.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/core/manifest.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/core/registry.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/middleware/__init__.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/middleware/auth.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/middleware/feedback.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/middleware/logging.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/middleware/metrics.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/middleware/rate_limit.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/observability/__init__.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/observability/concurrency.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/observability/metrics.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/observability/telemetry.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/optimize/__init__.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/optimize/dataset.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/optimize/loop.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/optimize/metrics.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/optimize/optimizer.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/optimize/report.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/optimize/runner.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/optimize/strategies.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/optimize/synthesizer.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/prompts/__init__.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/prompts/manager.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/protocols/__init__.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/protocols/decorators.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/providers/embeddings.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/py.typed +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/ui/.chainlit/config.toml +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/ui/__init__.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agentomatic/ui/chat.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agents/__init__.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agents/alpha/__init__.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agents/alpha/agent.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agents/alpha/api.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agents/alpha/config.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agents/alpha/prompts.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agents/alpha/schemas.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agents/alpha/state.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agents/beta/__init__.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agents/beta/agent.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agents/beta/api.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agents/beta/config.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agents/beta/prompts.json +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agents/beta/schemas.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/agents/beta/state.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/app/__init__.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/app/api.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/app/dependencies.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/app/main.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/app/settings.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/common/__init__.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/common/agent_state.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/common/api_decorators.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/common/base_agent.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/common/llm_factory.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/common/prompt_manager.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/src/common/utilities.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/tests/test_cli.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/tests/test_integration.py +0 -0
- {agentomatic-0.2.0 → agentomatic-0.3.0}/tests/test_optimize.py +0 -0
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## v0.3.0 (2026-06-14)
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
- Implement memory management, platform features, and router updates
|
|
9
|
+
([`5cf8aa8`](https://github.com/UnicoLab/agentomatic/commit/5cf8aa88ef750e2fa443948981aad2f1f9f1f9c4))
|
|
10
|
+
|
|
11
|
+
|
|
4
12
|
## v0.2.0 (2026-06-14)
|
|
5
13
|
|
|
6
14
|
### Documentation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentomatic
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.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
|
|
@@ -132,7 +132,7 @@ Create production-ready AI agent APIs with auto-discovery, auto-routing, streami
|
|
|
132
132
|
| Feature | Description |
|
|
133
133
|
|---|---|
|
|
134
134
|
| 🔍 **Auto-Discovery** | Drop an agent folder → endpoints appear automatically |
|
|
135
|
-
| 🚀 **
|
|
135
|
+
| 🚀 **25+ Endpoints Per Agent** | invoke, stream, chat, A2A, health, config, threads, memory, feedback |
|
|
136
136
|
| 🗄️ **Pluggable Storage** | MemoryStore, SQLAlchemy, or bring your own |
|
|
137
137
|
| 🔐 **Middleware Pipeline** | Auth, rate limiting, Prometheus metrics — all toggleable |
|
|
138
138
|
| 🎨 **Built-in Debug UI** | ChatGPT-like interface via Chainlit |
|
|
@@ -143,6 +143,17 @@ Create production-ready AI agent APIs with auto-discovery, auto-routing, streami
|
|
|
143
143
|
| ⚡ **Prompt Optimizer** | DSPy-inspired prompt optimization (7 strategies) |
|
|
144
144
|
| 🧪 **Data Synthesizer** | Auto-generate & augment eval datasets via LLM |
|
|
145
145
|
| 📊 **HTML Reports** | SVG charts, prompt diffs, experiment tracking |
|
|
146
|
+
| 🚦 **Human-in-the-Loop** | Suspend/resume execution with human approval gates |
|
|
147
|
+
| 🌳 **Thread Lineage** | First-class parent/child tracking with ancestry traversal |
|
|
148
|
+
| ⏰ **HITL TTL Expiry** | Auto-cleanup of stale suspended states (7-day default) |
|
|
149
|
+
| 🛡️ **LLM Failover** | Multi-provider fallback chains with telemetry |
|
|
150
|
+
| 🧬 **Thread Forking** | Clone conversations at any message index |
|
|
151
|
+
| 🔀 **A/B Prompt Routing** | Weight-based prompt version selection |
|
|
152
|
+
| 🪝 **State Hooks** | Before/after node interceptors for audit & telemetry |
|
|
153
|
+
| 🧠 **Conversation Memory** | Automatic session + long-term memory with windowing |
|
|
154
|
+
| 📝 **Auto-Summarization** | LLM-powered compression of long conversations |
|
|
155
|
+
| 📋 **Thread CRUD** | Full thread lifecycle management (create/update/delete/clear) |
|
|
156
|
+
| 💬 **Message Persistence** | Every turn auto-saved — history survives restarts |
|
|
146
157
|
|
|
147
158
|
## 🚀 Quick Start
|
|
148
159
|
|
|
@@ -317,6 +328,11 @@ Every agent gets 12+ endpoints automatically:
|
|
|
317
328
|
| `GET` | `/api/v1/{agent}/card` | A2A agent card |
|
|
318
329
|
| `POST` | `/api/v1/{agent}/a2a/tasks` | A2A task submission |
|
|
319
330
|
| `GET` | `/api/v1/{agent}/threads` | List threads |
|
|
331
|
+
| `POST` | `/api/v1/{agent}/threads/{id}/approve` | HITL: approve suspended state |
|
|
332
|
+
| `POST` | `/api/v1/{agent}/threads/{id}/reject` | HITL: reject suspended state |
|
|
333
|
+
| `GET` | `/api/v1/{agent}/threads/{id}/pending` | HITL: list pending approvals |
|
|
334
|
+
| `POST` | `/api/v1/{agent}/threads/{id}/fork` | Fork thread at message index |
|
|
335
|
+
| `GET` | `/api/v1/{agent}/threads/{id}/lineage` | Thread ancestry/descendant tree |
|
|
320
336
|
| ... | ... | + config, prompts, thread messages |
|
|
321
337
|
|
|
322
338
|
## 🛠️ Development
|
|
@@ -28,7 +28,7 @@ Create production-ready AI agent APIs with auto-discovery, auto-routing, streami
|
|
|
28
28
|
| Feature | Description |
|
|
29
29
|
|---|---|
|
|
30
30
|
| 🔍 **Auto-Discovery** | Drop an agent folder → endpoints appear automatically |
|
|
31
|
-
| 🚀 **
|
|
31
|
+
| 🚀 **25+ Endpoints Per Agent** | invoke, stream, chat, A2A, health, config, threads, memory, feedback |
|
|
32
32
|
| 🗄️ **Pluggable Storage** | MemoryStore, SQLAlchemy, or bring your own |
|
|
33
33
|
| 🔐 **Middleware Pipeline** | Auth, rate limiting, Prometheus metrics — all toggleable |
|
|
34
34
|
| 🎨 **Built-in Debug UI** | ChatGPT-like interface via Chainlit |
|
|
@@ -39,6 +39,17 @@ Create production-ready AI agent APIs with auto-discovery, auto-routing, streami
|
|
|
39
39
|
| ⚡ **Prompt Optimizer** | DSPy-inspired prompt optimization (7 strategies) |
|
|
40
40
|
| 🧪 **Data Synthesizer** | Auto-generate & augment eval datasets via LLM |
|
|
41
41
|
| 📊 **HTML Reports** | SVG charts, prompt diffs, experiment tracking |
|
|
42
|
+
| 🚦 **Human-in-the-Loop** | Suspend/resume execution with human approval gates |
|
|
43
|
+
| 🌳 **Thread Lineage** | First-class parent/child tracking with ancestry traversal |
|
|
44
|
+
| ⏰ **HITL TTL Expiry** | Auto-cleanup of stale suspended states (7-day default) |
|
|
45
|
+
| 🛡️ **LLM Failover** | Multi-provider fallback chains with telemetry |
|
|
46
|
+
| 🧬 **Thread Forking** | Clone conversations at any message index |
|
|
47
|
+
| 🔀 **A/B Prompt Routing** | Weight-based prompt version selection |
|
|
48
|
+
| 🪝 **State Hooks** | Before/after node interceptors for audit & telemetry |
|
|
49
|
+
| 🧠 **Conversation Memory** | Automatic session + long-term memory with windowing |
|
|
50
|
+
| 📝 **Auto-Summarization** | LLM-powered compression of long conversations |
|
|
51
|
+
| 📋 **Thread CRUD** | Full thread lifecycle management (create/update/delete/clear) |
|
|
52
|
+
| 💬 **Message Persistence** | Every turn auto-saved — history survives restarts |
|
|
42
53
|
|
|
43
54
|
## 🚀 Quick Start
|
|
44
55
|
|
|
@@ -213,6 +224,11 @@ Every agent gets 12+ endpoints automatically:
|
|
|
213
224
|
| `GET` | `/api/v1/{agent}/card` | A2A agent card |
|
|
214
225
|
| `POST` | `/api/v1/{agent}/a2a/tasks` | A2A task submission |
|
|
215
226
|
| `GET` | `/api/v1/{agent}/threads` | List threads |
|
|
227
|
+
| `POST` | `/api/v1/{agent}/threads/{id}/approve` | HITL: approve suspended state |
|
|
228
|
+
| `POST` | `/api/v1/{agent}/threads/{id}/reject` | HITL: reject suspended state |
|
|
229
|
+
| `GET` | `/api/v1/{agent}/threads/{id}/pending` | HITL: list pending approvals |
|
|
230
|
+
| `POST` | `/api/v1/{agent}/threads/{id}/fork` | Fork thread at message index |
|
|
231
|
+
| `GET` | `/api/v1/{agent}/threads/{id}/lineage` | Thread ancestry/descendant tree |
|
|
216
232
|
| ... | ... | + config, prompts, thread messages |
|
|
217
233
|
|
|
218
234
|
## 🛠️ Development
|
|
@@ -37,6 +37,8 @@ platform = AgentPlatform.from_folder(
|
|
|
37
37
|
enable_metrics=True,
|
|
38
38
|
enable_feedback=True,
|
|
39
39
|
enable_telemetry=True,
|
|
40
|
+
max_history_messages=50,
|
|
41
|
+
summarize_after=30,
|
|
40
42
|
)
|
|
41
43
|
```
|
|
42
44
|
|
|
@@ -62,9 +64,17 @@ platform = AgentPlatform.from_folder(
|
|
|
62
64
|
|
|
63
65
|
### 4. Storage Backend
|
|
64
66
|
|
|
65
|
-
- **`store`** (type: `BaseStore | None`, default: `None`): Instance of a storage adapter (e.g. `MemoryStore` or `SQLAlchemyStore`) used to save message threads and rating logs.
|
|
67
|
+
- **`store`** (type: `BaseStore | None`, default: `None`): Instance of a storage adapter (e.g. `MemoryStore` or `SQLAlchemyStore`) used to save message threads, conversation history, and rating logs.
|
|
66
68
|
|
|
67
|
-
### 5.
|
|
69
|
+
### 5. Memory & Conversation
|
|
70
|
+
|
|
71
|
+
- **`max_history_messages`** (type: `int`, default: `50`): Maximum number of messages to load from the thread store into the agent's context window. When the conversation exceeds this limit, older messages are windowed out or summarised.
|
|
72
|
+
- **`summarize_after`** (type: `int`, default: `30`): When the message count in a thread exceeds this threshold, older messages are automatically summarised using the configured LLM and prepended as a `[Conversation Summary]` system message.
|
|
73
|
+
|
|
74
|
+
> [!TIP]
|
|
75
|
+
> These values can also be overridden per-request using the `max_history` field on `AgentChatRequest`, giving frontends full control over how much context each invocation receives.
|
|
76
|
+
|
|
77
|
+
### 6. Security & Rate Limiting
|
|
68
78
|
|
|
69
79
|
- **`enable_auth`** (type: `bool`, default: `False`): If `True`, mounts Key Authentication middleware on all agent routes.
|
|
70
80
|
- **`auth_api_key`** (type: `str`, default: `""`): The secret API key token required by clients when `enable_auth` is enabled.
|
|
@@ -337,3 +337,353 @@ def audit_output_hook(agent_name: str, result: dict):
|
|
|
337
337
|
|
|
338
338
|
platform.register_after_node_hook(audit_output_hook)
|
|
339
339
|
```
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## 🛡️ 8. Safe Checkpoint Serialization
|
|
344
|
+
|
|
345
|
+
LangGraph checkpoints can contain non-JSON-serializable Python objects (datetimes, bytes, custom classes). The `AgentomaticCheckpointer` automatically handles this via a safe JSON round-trip:
|
|
346
|
+
|
|
347
|
+
```python
|
|
348
|
+
from agentomatic.storage.checkpointer import AgentomaticCheckpointer, _ensure_json_serializable
|
|
349
|
+
|
|
350
|
+
# Objects like datetimes, bytes, and custom classes are safely converted
|
|
351
|
+
data = _ensure_json_serializable({"ts": datetime.now(), "raw": b"bytes"})
|
|
352
|
+
# → {"ts": "2026-06-14 12:00:00", "raw": "b'bytes'"}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
This happens transparently inside `aput()` — no user configuration needed. All values are round-tripped through `json.dumps(obj, default=str)` → `json.loads()`.
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## ⏰ 9. HITL TTL Expiry & Cleanup
|
|
360
|
+
|
|
361
|
+
Suspended states automatically receive a 7-day TTL (`expires_at`). This prevents stale suspended states from accumulating in the database when humans forget to approve or reject them.
|
|
362
|
+
|
|
363
|
+
### Automatic TTL
|
|
364
|
+
|
|
365
|
+
When `save_suspended_state()` is called, the `expires_at` field defaults to `now + 7 days`:
|
|
366
|
+
|
|
367
|
+
```python
|
|
368
|
+
state = await store.save_suspended_state(
|
|
369
|
+
approval_id="app_xyz",
|
|
370
|
+
thread_id="thread_1",
|
|
371
|
+
agent_name="my_agent",
|
|
372
|
+
node_name="approval_node",
|
|
373
|
+
state_json={"action": "delete_account"},
|
|
374
|
+
)
|
|
375
|
+
print(state["expires_at"]) # 7 days from now
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Cleanup
|
|
379
|
+
|
|
380
|
+
Call `cleanup_expired_states()` on a schedule (e.g. cron, background task) to purge expired states:
|
|
381
|
+
|
|
382
|
+
```python
|
|
383
|
+
# Clean up expired suspended states
|
|
384
|
+
count = await store.cleanup_expired_states()
|
|
385
|
+
print(f"Cleaned up {count} expired states")
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
This works identically on `MemoryStore` and `SQLAlchemyStore`.
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## 🌳 10. Thread Lineage Tracking
|
|
393
|
+
|
|
394
|
+
Forked threads now have **first-class lineage fields** instead of metadata-based tracking:
|
|
395
|
+
|
|
396
|
+
| Field | Type | Description |
|
|
397
|
+
|---|---|---|
|
|
398
|
+
| `parent_thread_id` | `str \| None` | ID of the parent thread (null for root threads) |
|
|
399
|
+
| `fork_message_index` | `int \| None` | Message index where the fork occurred |
|
|
400
|
+
|
|
401
|
+
### Querying Lineage
|
|
402
|
+
|
|
403
|
+
Use `get_thread_lineage()` to traverse the full ancestor/descendant tree:
|
|
404
|
+
|
|
405
|
+
```python
|
|
406
|
+
# Fork a thread
|
|
407
|
+
forked = await store.fork_thread("root_thread", 2, "child_thread")
|
|
408
|
+
print(forked["parent_thread_id"]) # "root_thread"
|
|
409
|
+
|
|
410
|
+
# Get full lineage
|
|
411
|
+
lineage = await store.get_thread_lineage("child_thread")
|
|
412
|
+
print(lineage["ancestors"]) # [root_thread_dict]
|
|
413
|
+
print(lineage["descendants"]) # []
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### REST Endpoint
|
|
417
|
+
|
|
418
|
+
```http
|
|
419
|
+
GET /api/v1/{agent}/threads/{thread_id}/lineage
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
**Response:**
|
|
423
|
+
```json
|
|
424
|
+
{
|
|
425
|
+
"thread_id": "child_thread",
|
|
426
|
+
"ancestors": [{"id": "root_thread", ...}],
|
|
427
|
+
"descendants": [{"id": "grandchild_thread", ...}]
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
## 📊 11. LLM Failover Telemetry
|
|
434
|
+
|
|
435
|
+
Track failover events for observability and alerting:
|
|
436
|
+
|
|
437
|
+
```python
|
|
438
|
+
from agentomatic.providers.llm import record_failover, get_failover_count, reset_llm
|
|
439
|
+
|
|
440
|
+
# Record a failover event
|
|
441
|
+
record_failover("openai", "azure", "RateLimitError")
|
|
442
|
+
# Emits: 🔄 LLM failover #1: openai -> azure | Error: RateLimitError
|
|
443
|
+
|
|
444
|
+
# Check current count
|
|
445
|
+
print(get_failover_count()) # 1
|
|
446
|
+
|
|
447
|
+
# Reset (typically in tests)
|
|
448
|
+
reset_llm() # Also resets failover counter
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
The failover chain now also passes `exceptions_to_handle=(Exception,)` to `with_fallbacks()`, ensuring **any** exception triggers the fallback chain, not just specific ones.
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## 🧠 12. Conversation Memory & Session Management
|
|
456
|
+
|
|
457
|
+
Agentomatic provides **automatic conversation memory** for all deployed agents. When a thread store is configured, every `/chat` and `/invoke` call automatically:
|
|
458
|
+
|
|
459
|
+
1. **Loads prior conversation history** into the agent's `messages` state
|
|
460
|
+
2. **Invokes the agent** with full conversational context
|
|
461
|
+
3. **Persists** both user and assistant messages to the store
|
|
462
|
+
4. **Summarises** older messages when the conversation grows long
|
|
463
|
+
|
|
464
|
+
```
|
|
465
|
+
Frontend Agentomatic Store
|
|
466
|
+
│ │ │
|
|
467
|
+
│ POST /chat │ │
|
|
468
|
+
│ {content, thread_id} │ │
|
|
469
|
+
│───────────────────────────>│ │
|
|
470
|
+
│ │ get_messages(thread_id) │
|
|
471
|
+
│ │──────────────────────────>│
|
|
472
|
+
│ │ [msg1, msg2, ...] │
|
|
473
|
+
│ │<──────────────────────────│
|
|
474
|
+
│ │ │
|
|
475
|
+
│ │ ── Windowing ── │
|
|
476
|
+
│ │ ── Summarization ── │
|
|
477
|
+
│ │ │
|
|
478
|
+
│ │ ainvoke(state) │
|
|
479
|
+
│ │ (state.messages = │
|
|
480
|
+
│ │ history + current) │
|
|
481
|
+
│ │ │
|
|
482
|
+
│ │ add_message(user) │
|
|
483
|
+
│ │──────────────────────────>│
|
|
484
|
+
│ │ add_message(assistant) │
|
|
485
|
+
│ │──────────────────────────>│
|
|
486
|
+
│ │ │
|
|
487
|
+
│ {response, thread_id, │ │
|
|
488
|
+
│ history_loaded: 12} │ │
|
|
489
|
+
│<───────────────────────────│ │
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### Configuration
|
|
493
|
+
|
|
494
|
+
Memory is automatically enabled when a `store` is provided to `AgentPlatform`:
|
|
495
|
+
|
|
496
|
+
```python
|
|
497
|
+
from agentomatic import AgentPlatform
|
|
498
|
+
from agentomatic.storage import MemoryStore
|
|
499
|
+
|
|
500
|
+
platform = AgentPlatform.from_folder(
|
|
501
|
+
"agents/",
|
|
502
|
+
store=MemoryStore(), # enables memory + thread management
|
|
503
|
+
max_history_messages=50, # max messages in context window
|
|
504
|
+
summarize_after=30, # summarize when exceeding this count
|
|
505
|
+
)
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### Chat Request with Memory
|
|
509
|
+
|
|
510
|
+
```python
|
|
511
|
+
# Frontend sends a message with thread_id
|
|
512
|
+
POST /api/v1/my_agent/chat
|
|
513
|
+
{
|
|
514
|
+
"content": "What's our PTO policy?",
|
|
515
|
+
"thread_id": "thread_abc123", # reuse for multi-turn
|
|
516
|
+
"user_id": "user_42",
|
|
517
|
+
"context": { # arbitrary data for agent code
|
|
518
|
+
"user_role": "manager",
|
|
519
|
+
"department": "engineering"
|
|
520
|
+
},
|
|
521
|
+
"include_history": true, # default: true
|
|
522
|
+
"max_history": 20, # optional override
|
|
523
|
+
"persist": true, # default: true — auto-save messages
|
|
524
|
+
"prompt_version": "v1" # optional explicit prompt version
|
|
525
|
+
}
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
#### Override: Supply Your Own Messages
|
|
529
|
+
|
|
530
|
+
If the frontend manages its own conversation state, it can pass `messages` directly — this **skips** automatic history loading from the store:
|
|
531
|
+
|
|
532
|
+
```python
|
|
533
|
+
POST /api/v1/my_agent/chat
|
|
534
|
+
{
|
|
535
|
+
"content": "Follow-up question",
|
|
536
|
+
"messages": [
|
|
537
|
+
{"role": "user", "content": "Previous question"},
|
|
538
|
+
{"role": "assistant", "content": "Previous answer"}
|
|
539
|
+
],
|
|
540
|
+
"persist": false # optional: don't save to store
|
|
541
|
+
}
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
#### Response
|
|
545
|
+
|
|
546
|
+
The response includes all agent output fields plus conversation metadata:
|
|
547
|
+
|
|
548
|
+
```json
|
|
549
|
+
{
|
|
550
|
+
"response": "Based on our company handbook...",
|
|
551
|
+
"thread_id": "thread_abc123",
|
|
552
|
+
"agent_type": "hr-agent",
|
|
553
|
+
"suggestions": ["Ask about sick days", "View calendar"],
|
|
554
|
+
"citations": [...],
|
|
555
|
+
"steps_taken": ["search_policy_db", "generate_response"],
|
|
556
|
+
"context": {"retrieved_documents": [...]},
|
|
557
|
+
"duration_ms": 234.5,
|
|
558
|
+
"metadata": {"prompt_version": "v1", "source": "mobile_app"},
|
|
559
|
+
"history_loaded": 12
|
|
560
|
+
}
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
| Response Field | Description |
|
|
564
|
+
|----------------|-------------|
|
|
565
|
+
| `response` | Agent's text response |
|
|
566
|
+
| `thread_id` | Thread ID (auto-created if not provided) |
|
|
567
|
+
| `agent_type` | Agent slug identifier |
|
|
568
|
+
| `suggestions` | Follow-up suggestions from agent |
|
|
569
|
+
| `citations` | Source citations from agent |
|
|
570
|
+
| `steps_taken` | Processing steps the agent took |
|
|
571
|
+
| `context` | Context data returned by agent (RAG docs, search results, etc.) |
|
|
572
|
+
| `metadata` | Merged metadata (request + agent + prompt_version) |
|
|
573
|
+
| `history_loaded` | Number of prior messages loaded into context |
|
|
574
|
+
| `duration_ms` | Processing time in milliseconds |
|
|
575
|
+
|
|
576
|
+
### Windowing & Summarization
|
|
577
|
+
|
|
578
|
+
When conversations grow long, agentomatic automatically:
|
|
579
|
+
|
|
580
|
+
1. **Windows** — keeps only the latest `max_messages` in context
|
|
581
|
+
2. **Summarises** — compresses older messages into a summary via the LLM
|
|
582
|
+
3. **Prepends** — adds `[Conversation Summary]` as a system message
|
|
583
|
+
|
|
584
|
+
```python
|
|
585
|
+
# Example: After 50 messages, the agent receives:
|
|
586
|
+
state["messages"] = [
|
|
587
|
+
SystemMessage("[Conversation Summary]\nUser discussed PTO policy..."),
|
|
588
|
+
HumanMessage("Question 48"),
|
|
589
|
+
AIMessage("Answer 48"),
|
|
590
|
+
HumanMessage("Question 49"),
|
|
591
|
+
AIMessage("Answer 49"),
|
|
592
|
+
HumanMessage("Current question"), # ← latest
|
|
593
|
+
]
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
If no LLM is available, a fallback summary is used (simple truncated concatenation).
|
|
597
|
+
|
|
598
|
+
### Using `ConversationMemoryManager` Directly
|
|
599
|
+
|
|
600
|
+
For advanced use cases, you can use the manager directly:
|
|
601
|
+
|
|
602
|
+
```python
|
|
603
|
+
from agentomatic.core.memory_manager import ConversationMemoryManager
|
|
604
|
+
from agentomatic.storage import MemoryStore
|
|
605
|
+
|
|
606
|
+
store = MemoryStore()
|
|
607
|
+
mgr = ConversationMemoryManager(
|
|
608
|
+
store,
|
|
609
|
+
max_messages=50,
|
|
610
|
+
summarize_after=30,
|
|
611
|
+
summary_token_target=200,
|
|
612
|
+
)
|
|
613
|
+
|
|
614
|
+
# Load history
|
|
615
|
+
thread_id = await mgr.get_or_create_thread("thread_123", "user_1", "my-agent")
|
|
616
|
+
messages = await mgr.load_history(thread_id, "What's the weather?")
|
|
617
|
+
|
|
618
|
+
# Save a turn
|
|
619
|
+
await mgr.save_turn(thread_id, "What's the weather?", "It's sunny!", agent_name="weather-bot")
|
|
620
|
+
|
|
621
|
+
# Get full conversation summary
|
|
622
|
+
summary = await mgr.get_conversation_summary(thread_id)
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
---
|
|
626
|
+
|
|
627
|
+
## 📋 13. Thread Management API
|
|
628
|
+
|
|
629
|
+
Agentomatic provides a full CRUD API for conversation threads.
|
|
630
|
+
|
|
631
|
+
### Endpoints
|
|
632
|
+
|
|
633
|
+
| Method | Path | Description |
|
|
634
|
+
|--------|------|-------------|
|
|
635
|
+
| `POST` | `/threads` | Create a thread explicitly |
|
|
636
|
+
| `GET` | `/threads` | List threads (filterable by `user_id`) |
|
|
637
|
+
| `GET` | `/threads/{id}` | Get a specific thread |
|
|
638
|
+
| `PATCH` | `/threads/{id}` | Update thread title/metadata |
|
|
639
|
+
| `DELETE` | `/threads/{id}` | Delete thread and all messages |
|
|
640
|
+
| `GET` | `/threads/{id}/messages` | Get messages with pagination |
|
|
641
|
+
| `DELETE` | `/threads/{id}/messages` | Clear messages (keep thread) |
|
|
642
|
+
| `GET` | `/threads/{id}/summary` | Generate conversation summary |
|
|
643
|
+
| `POST` | `/threads/{id}/fork` | Fork thread at a message index |
|
|
644
|
+
| `GET` | `/threads/{id}/lineage` | Get thread ancestry tree |
|
|
645
|
+
|
|
646
|
+
### Examples
|
|
647
|
+
|
|
648
|
+
```python
|
|
649
|
+
# Create a thread
|
|
650
|
+
POST /api/v1/my_agent/threads
|
|
651
|
+
{"user_id": "user_42", "title": "Onboarding questions"}
|
|
652
|
+
|
|
653
|
+
# Get paginated messages
|
|
654
|
+
GET /api/v1/my_agent/threads/thread_abc/messages?limit=20&offset=0
|
|
655
|
+
|
|
656
|
+
# Clear conversation history
|
|
657
|
+
DELETE /api/v1/my_agent/threads/thread_abc/messages
|
|
658
|
+
|
|
659
|
+
# Update thread title
|
|
660
|
+
PATCH /api/v1/my_agent/threads/thread_abc
|
|
661
|
+
{"title": "Updated title"}
|
|
662
|
+
|
|
663
|
+
# Get conversation summary
|
|
664
|
+
GET /api/v1/my_agent/threads/thread_abc/summary
|
|
665
|
+
# → {"thread_id": "thread_abc", "summary": "User asked about..."}
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
### Frontend Integration Guide
|
|
669
|
+
|
|
670
|
+
For frontend applications (React, Vue, mobile), here's the recommended flow:
|
|
671
|
+
|
|
672
|
+
```
|
|
673
|
+
1. Start Session
|
|
674
|
+
POST /threads → get thread_id
|
|
675
|
+
|
|
676
|
+
2. Send Messages
|
|
677
|
+
POST /chat {content, thread_id} → get response
|
|
678
|
+
|
|
679
|
+
3. Load History (on page reload)
|
|
680
|
+
GET /threads/{id}/messages?limit=50 → display messages
|
|
681
|
+
|
|
682
|
+
4. Clear Conversation
|
|
683
|
+
DELETE /threads/{id}/messages → reset
|
|
684
|
+
|
|
685
|
+
5. List User's Conversations
|
|
686
|
+
GET /threads?user_id=xxx → sidebar list
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
All thread data is persisted in the configured store (MemoryStore for dev, SQLAlchemyStore for production).
|
|
@@ -43,6 +43,73 @@ Agentomatic searches `schemas.py` for class definitions matching one of these na
|
|
|
43
43
|
|
|
44
44
|
---
|
|
45
45
|
|
|
46
|
+
## 📋 Default Schema Reference
|
|
47
|
+
|
|
48
|
+
### `AgentInvokeRequest` (default input)
|
|
49
|
+
|
|
50
|
+
| Field | Type | Default | Description |
|
|
51
|
+
|-------|------|---------|-------------|
|
|
52
|
+
| `query` | `str` | *required* | User query or input |
|
|
53
|
+
| `user_id` | `str` | `"default-user"` | User identifier |
|
|
54
|
+
| `context` | `dict` | `{}` | Additional context — passed to agent as `state["context"]` |
|
|
55
|
+
| `thread_id` | `str \| None` | `None` | Thread ID for conversation continuity |
|
|
56
|
+
| `prompt_version` | `str` | `"v1"` | Prompt version to use |
|
|
57
|
+
| `temperature` | `float \| None` | `None` | Temperature override (0.0–2.0) |
|
|
58
|
+
| `max_tokens` | `int \| None` | `None` | Max tokens override |
|
|
59
|
+
| `metadata` | `dict` | `{}` | Extra metadata |
|
|
60
|
+
|
|
61
|
+
### `AgentInvokeResponse` (default output)
|
|
62
|
+
|
|
63
|
+
| Field | Type | Description |
|
|
64
|
+
|-------|------|-------------|
|
|
65
|
+
| `response` | `str` | Agent response text |
|
|
66
|
+
| `agent_type` | `str` | Agent slug |
|
|
67
|
+
| `thread_id` | `str \| None` | Thread ID |
|
|
68
|
+
| `suggestions` | `list[str]` | Follow-up suggestions |
|
|
69
|
+
| `citations` | `list[dict]` | Source citations |
|
|
70
|
+
| `steps_taken` | `list[str]` | Processing steps taken |
|
|
71
|
+
| `context` | `Any` | Context data returned by the agent (RAG documents, etc.) |
|
|
72
|
+
| `metadata` | `dict` | Response metadata (includes `prompt_version`) |
|
|
73
|
+
| `duration_ms` | `float` | Processing time in milliseconds |
|
|
74
|
+
|
|
75
|
+
### `AgentChatRequest` (chat endpoint)
|
|
76
|
+
|
|
77
|
+
| Field | Type | Default | Description |
|
|
78
|
+
|-------|------|---------|-------------|
|
|
79
|
+
| `content` | `str` | *required* | User message |
|
|
80
|
+
| `user_id` | `str` | `"default-user"` | User identifier |
|
|
81
|
+
| `thread_id` | `str \| None` | `None` | Existing thread ID (auto-created if omitted) |
|
|
82
|
+
| `context` | `dict` | `{}` | Arbitrary context dict for agent code to consume |
|
|
83
|
+
| `metadata` | `dict` | `{}` | Extra metadata |
|
|
84
|
+
| `messages` | `list[dict] \| None` | `None` | Override: supply your own message history (skips auto-loading) |
|
|
85
|
+
| `include_history` | `bool` | `true` | Load conversation history from store |
|
|
86
|
+
| `max_history` | `int \| None` | `None` | Max messages to load (overrides agent default) |
|
|
87
|
+
| `persist` | `bool` | `true` | Auto-save messages to the store after invocation |
|
|
88
|
+
| `prompt_version` | `str` | `"v1"` | Prompt version to use |
|
|
89
|
+
|
|
90
|
+
### `BaseAgentState` (agent state dict)
|
|
91
|
+
|
|
92
|
+
This is the TypedDict available in your agent's `node_fn(state)`:
|
|
93
|
+
|
|
94
|
+
| Field | Type | Description |
|
|
95
|
+
|-------|------|-------------|
|
|
96
|
+
| `messages` | `list` | LangChain messages (auto-loaded or user-supplied) |
|
|
97
|
+
| `thread_id` | `str` | Thread ID |
|
|
98
|
+
| `user_id` | `str` | User identifier |
|
|
99
|
+
| `current_query` | `str` | The current user query |
|
|
100
|
+
| `context` | `dict` | Arbitrary context from the frontend/caller |
|
|
101
|
+
| `metadata` | `dict` | Request metadata |
|
|
102
|
+
| `prompt_version` | `str` | Resolved prompt version |
|
|
103
|
+
| `response` | `str` | Agent response (set by your code) |
|
|
104
|
+
| `agent_type` | `str` | Agent slug (set by your code) |
|
|
105
|
+
| `suggestions` | `list[str]` | Follow-up suggestions |
|
|
106
|
+
| `citations` | `list[dict]` | Source citations |
|
|
107
|
+
| `steps_taken` | `list[str]` | Processing steps taken |
|
|
108
|
+
| `routing_decision` | `str` | Routing decision (for orchestrators) |
|
|
109
|
+
| `error` | `str \| None` | Error message if any |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
46
113
|
## 🛠️ Defining Custom Schemas
|
|
47
114
|
|
|
48
115
|
To define custom models, simply import Pydantic's `BaseModel` and declare your fields using type annotations and metadata helpers like `Field`.
|
|
@@ -191,14 +191,18 @@ Every storage adapter implements the following async interface methods:
|
|
|
191
191
|
| `async def add_message(...) -> dict` | **Required** | Save a new query/response message |
|
|
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
|
-
| `async def
|
|
195
|
-
| `async def
|
|
194
|
+
| `async def get_feedback(...) -> list[dict]` | Optional | Search feedback records |
|
|
195
|
+
| `async def get_stats() -> dict` | Optional | Return storage statistics (threads, messages, feedback counts) |
|
|
196
|
+
| `async def save_suspended_state(...) -> dict` | Optional | Save execution state for human approval (auto-sets 7-day TTL) |
|
|
196
197
|
| `async def get_suspended_state(id) -> dict \| None` | Optional | Retrieve a suspended state |
|
|
197
198
|
| `async def list_suspended_states(...) -> list[dict]` | Optional | List all pending suspended states |
|
|
198
199
|
| `async def delete_suspended_state(id) -> bool` | Optional | Delete suspended state on completion |
|
|
200
|
+
| `async def cleanup_expired_states() -> int` | Optional | Delete expired HITL states, returns count removed |
|
|
199
201
|
| `async def fork_thread(...) -> dict \| None` | Optional | Fork a conversation history up to index |
|
|
202
|
+
| `async def get_thread_lineage(id) -> dict` | Optional | Ancestry/descendant tree for a thread |
|
|
200
203
|
| `async def save_checkpoint(...) -> None` | Optional | Save a LangGraph checkpoint state |
|
|
201
204
|
| `async def get_checkpoint(...) -> dict \| None` | Optional | Retrieve a LangGraph checkpoint state |
|
|
202
205
|
| `async def list_checkpoints(...) -> list[dict]` | Optional | List checkpoints for a thread namespace |
|
|
203
206
|
|
|
204
207
|
> 🚦 *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).*
|
|
208
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "agentomatic"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.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"}
|
|
@@ -82,6 +82,7 @@ Changelog = "https://github.com/UnicoLab/agentomatic/blob/main/CHANGELOG.md"
|
|
|
82
82
|
|
|
83
83
|
|
|
84
84
|
|
|
85
|
+
|
|
85
86
|
[dependency-groups]
|
|
86
87
|
dev = [
|
|
87
88
|
"pytest>=8",
|
|
@@ -33,6 +33,7 @@ from agentomatic._version import __version__
|
|
|
33
33
|
|
|
34
34
|
# Core public API
|
|
35
35
|
from agentomatic.core.manifest import AgentManifest, RegisteredAgent
|
|
36
|
+
from agentomatic.core.memory_manager import ConversationMemoryManager
|
|
36
37
|
from agentomatic.core.platform import AgentPlatform
|
|
37
38
|
from agentomatic.core.registry import AgentRegistry
|
|
38
39
|
from agentomatic.core.state import BaseAgentState
|
|
@@ -48,6 +49,7 @@ __all__ = [
|
|
|
48
49
|
"RegisteredAgent",
|
|
49
50
|
"AgentRegistry",
|
|
50
51
|
"BaseAgentState",
|
|
52
|
+
"ConversationMemoryManager",
|
|
51
53
|
# Protocols
|
|
52
54
|
"APIResponse",
|
|
53
55
|
"handle_api_errors",
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from .lifespan import configure_logging, create_lifespan
|
|
6
6
|
from .manifest import AgentManifest, RegisteredAgent
|
|
7
|
+
from .memory_manager import ConversationMemoryManager
|
|
7
8
|
from .platform import AgentPlatform
|
|
8
9
|
from .registry import AgentRegistry
|
|
9
10
|
from .router_factory import (
|
|
@@ -11,6 +12,12 @@ from .router_factory import (
|
|
|
11
12
|
AgentChatRequest,
|
|
12
13
|
AgentInvokeRequest,
|
|
13
14
|
AgentInvokeResponse,
|
|
15
|
+
AgentSuspendedException,
|
|
16
|
+
ApproveSuspendedRequest,
|
|
17
|
+
CreateThreadRequest,
|
|
18
|
+
ForkThreadRequest,
|
|
19
|
+
RejectSuspendedRequest,
|
|
20
|
+
UpdateThreadRequest,
|
|
14
21
|
create_default_router,
|
|
15
22
|
)
|
|
16
23
|
from .state import BaseAgentState
|
|
@@ -23,8 +30,15 @@ __all__ = [
|
|
|
23
30
|
"AgentManifest",
|
|
24
31
|
"AgentPlatform",
|
|
25
32
|
"AgentRegistry",
|
|
33
|
+
"AgentSuspendedException",
|
|
34
|
+
"ApproveSuspendedRequest",
|
|
26
35
|
"BaseAgentState",
|
|
36
|
+
"ConversationMemoryManager",
|
|
37
|
+
"CreateThreadRequest",
|
|
38
|
+
"ForkThreadRequest",
|
|
27
39
|
"RegisteredAgent",
|
|
40
|
+
"RejectSuspendedRequest",
|
|
41
|
+
"UpdateThreadRequest",
|
|
28
42
|
"configure_logging",
|
|
29
43
|
"create_default_router",
|
|
30
44
|
"create_lifespan",
|