aegra-api 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. aegra_api-0.1.0/.gitignore +32 -0
  2. aegra_api-0.1.0/PKG-INFO +244 -0
  3. aegra_api-0.1.0/README.md +202 -0
  4. aegra_api-0.1.0/alembic/env.py +100 -0
  5. aegra_api-0.1.0/alembic/script.py.mako +24 -0
  6. aegra_api-0.1.0/alembic/versions/20250817172544_initial_schema.py +196 -0
  7. aegra_api-0.1.0/alembic/versions/20250830161758_add_context.py +43 -0
  8. aegra_api-0.1.0/alembic/versions/20250831174511_add_cascade_delete_for_runs_thread_fkey.py +42 -0
  9. aegra_api-0.1.0/alembic/versions/20250913193817_add_version_table.py +82 -0
  10. aegra_api-0.1.0/alembic/versions/20250913213535_add_metadata_for_assistant_table_and_.py +76 -0
  11. aegra_api-0.1.0/alembic/versions/20251115152415_migrate_run_status_to_langgraph_.py +70 -0
  12. aegra_api-0.1.0/alembic.ini +107 -0
  13. aegra_api-0.1.0/pyproject.toml +109 -0
  14. aegra_api-0.1.0/src/aegra_api/__init__.py +3 -0
  15. aegra_api-0.1.0/src/aegra_api/api/__init__.py +1 -0
  16. aegra_api-0.1.0/src/aegra_api/api/assistants.py +235 -0
  17. aegra_api-0.1.0/src/aegra_api/api/runs.py +1110 -0
  18. aegra_api-0.1.0/src/aegra_api/api/store.py +200 -0
  19. aegra_api-0.1.0/src/aegra_api/api/threads.py +761 -0
  20. aegra_api-0.1.0/src/aegra_api/config.py +204 -0
  21. aegra_api-0.1.0/src/aegra_api/constants.py +5 -0
  22. aegra_api-0.1.0/src/aegra_api/core/__init__.py +0 -0
  23. aegra_api-0.1.0/src/aegra_api/core/app_loader.py +91 -0
  24. aegra_api-0.1.0/src/aegra_api/core/auth_ctx.py +65 -0
  25. aegra_api-0.1.0/src/aegra_api/core/auth_deps.py +186 -0
  26. aegra_api-0.1.0/src/aegra_api/core/auth_handlers.py +248 -0
  27. aegra_api-0.1.0/src/aegra_api/core/auth_middleware.py +331 -0
  28. aegra_api-0.1.0/src/aegra_api/core/database.py +123 -0
  29. aegra_api-0.1.0/src/aegra_api/core/health.py +131 -0
  30. aegra_api-0.1.0/src/aegra_api/core/orm.py +165 -0
  31. aegra_api-0.1.0/src/aegra_api/core/route_merger.py +69 -0
  32. aegra_api-0.1.0/src/aegra_api/core/serializers/__init__.py +7 -0
  33. aegra_api-0.1.0/src/aegra_api/core/serializers/base.py +22 -0
  34. aegra_api-0.1.0/src/aegra_api/core/serializers/general.py +54 -0
  35. aegra_api-0.1.0/src/aegra_api/core/serializers/langgraph.py +102 -0
  36. aegra_api-0.1.0/src/aegra_api/core/sse.py +178 -0
  37. aegra_api-0.1.0/src/aegra_api/main.py +303 -0
  38. aegra_api-0.1.0/src/aegra_api/middleware/__init__.py +4 -0
  39. aegra_api-0.1.0/src/aegra_api/middleware/double_encoded_json.py +74 -0
  40. aegra_api-0.1.0/src/aegra_api/middleware/logger_middleware.py +95 -0
  41. aegra_api-0.1.0/src/aegra_api/models/__init__.py +76 -0
  42. aegra_api-0.1.0/src/aegra_api/models/assistants.py +81 -0
  43. aegra_api-0.1.0/src/aegra_api/models/auth.py +62 -0
  44. aegra_api-0.1.0/src/aegra_api/models/enums.py +29 -0
  45. aegra_api-0.1.0/src/aegra_api/models/errors.py +29 -0
  46. aegra_api-0.1.0/src/aegra_api/models/runs.py +124 -0
  47. aegra_api-0.1.0/src/aegra_api/models/store.py +67 -0
  48. aegra_api-0.1.0/src/aegra_api/models/threads.py +152 -0
  49. aegra_api-0.1.0/src/aegra_api/observability/__init__.py +1 -0
  50. aegra_api-0.1.0/src/aegra_api/observability/base.py +88 -0
  51. aegra_api-0.1.0/src/aegra_api/observability/otel.py +133 -0
  52. aegra_api-0.1.0/src/aegra_api/observability/setup.py +27 -0
  53. aegra_api-0.1.0/src/aegra_api/observability/targets/__init__.py +11 -0
  54. aegra_api-0.1.0/src/aegra_api/observability/targets/base.py +18 -0
  55. aegra_api-0.1.0/src/aegra_api/observability/targets/langfuse.py +33 -0
  56. aegra_api-0.1.0/src/aegra_api/observability/targets/otlp.py +38 -0
  57. aegra_api-0.1.0/src/aegra_api/observability/targets/phoenix.py +24 -0
  58. aegra_api-0.1.0/src/aegra_api/services/__init__.py +0 -0
  59. aegra_api-0.1.0/src/aegra_api/services/assistant_service.py +569 -0
  60. aegra_api-0.1.0/src/aegra_api/services/base_broker.py +59 -0
  61. aegra_api-0.1.0/src/aegra_api/services/broker.py +141 -0
  62. aegra_api-0.1.0/src/aegra_api/services/event_converter.py +157 -0
  63. aegra_api-0.1.0/src/aegra_api/services/event_store.py +196 -0
  64. aegra_api-0.1.0/src/aegra_api/services/graph_streaming.py +433 -0
  65. aegra_api-0.1.0/src/aegra_api/services/langgraph_service.py +456 -0
  66. aegra_api-0.1.0/src/aegra_api/services/streaming_service.py +362 -0
  67. aegra_api-0.1.0/src/aegra_api/services/thread_state_service.py +128 -0
  68. aegra_api-0.1.0/src/aegra_api/settings.py +124 -0
  69. aegra_api-0.1.0/src/aegra_api/utils/__init__.py +3 -0
  70. aegra_api-0.1.0/src/aegra_api/utils/assistants.py +23 -0
  71. aegra_api-0.1.0/src/aegra_api/utils/run_utils.py +60 -0
  72. aegra_api-0.1.0/src/aegra_api/utils/setup_logging.py +122 -0
  73. aegra_api-0.1.0/src/aegra_api/utils/sse_utils.py +26 -0
  74. aegra_api-0.1.0/src/aegra_api/utils/status_compat.py +57 -0
  75. aegra_api-0.1.0/tests/README.md +197 -0
  76. aegra_api-0.1.0/tests/__init__.py +0 -0
  77. aegra_api-0.1.0/tests/conftest.py +199 -0
  78. aegra_api-0.1.0/tests/e2e/__init__.py +0 -0
  79. aegra_api-0.1.0/tests/e2e/_utils.py +69 -0
  80. aegra_api-0.1.0/tests/e2e/conftest.py +7 -0
  81. aegra_api-0.1.0/tests/e2e/manual_auth_tests/README.md +64 -0
  82. aegra_api-0.1.0/tests/e2e/manual_auth_tests/__init__.py +1 -0
  83. aegra_api-0.1.0/tests/e2e/manual_auth_tests/conftest.py +52 -0
  84. aegra_api-0.1.0/tests/e2e/manual_auth_tests/test_auth_e2e.py +324 -0
  85. aegra_api-0.1.0/tests/e2e/manual_auth_tests/test_authorization_handlers_e2e.py +239 -0
  86. aegra_api-0.1.0/tests/e2e/test_assistants/__init__.py +0 -0
  87. aegra_api-0.1.0/tests/e2e/test_assistants/test_assistant_deletion.py +185 -0
  88. aegra_api-0.1.0/tests/e2e/test_assistants/test_assistant_graph.py +277 -0
  89. aegra_api-0.1.0/tests/e2e/test_assistants/test_assistant_search.py +153 -0
  90. aegra_api-0.1.0/tests/e2e/test_assistants/test_assistant_version.py +107 -0
  91. aegra_api-0.1.0/tests/e2e/test_custom_routes/__init__.py +1 -0
  92. aegra_api-0.1.0/tests/e2e/test_custom_routes/test_custom_routes_e2e.py +69 -0
  93. aegra_api-0.1.0/tests/e2e/test_human_in_loop/__init__.py +0 -0
  94. aegra_api-0.1.0/tests/e2e/test_human_in_loop/test_human_in_loop.py +814 -0
  95. aegra_api-0.1.0/tests/e2e/test_runs/__init__.py +0 -0
  96. aegra_api-0.1.0/tests/e2e/test_runs/test_background_run_join.py +151 -0
  97. aegra_api-0.1.0/tests/e2e/test_runs/test_cancel_run_e2e.py +316 -0
  98. aegra_api-0.1.0/tests/e2e/test_runs/test_run_join_output.py +73 -0
  99. aegra_api-0.1.0/tests/e2e/test_runs/test_runs.py +299 -0
  100. aegra_api-0.1.0/tests/e2e/test_store/__init__.py +0 -0
  101. aegra_api-0.1.0/tests/e2e/test_store/test_store.py +63 -0
  102. aegra_api-0.1.0/tests/e2e/test_streaming/__init__.py +0 -0
  103. aegra_api-0.1.0/tests/e2e/test_streaming/test_chat_streaming.py +77 -0
  104. aegra_api-0.1.0/tests/e2e/test_streaming/test_events_mode.py +172 -0
  105. aegra_api-0.1.0/tests/e2e/test_streaming/test_streaming_error_e2e.py +326 -0
  106. aegra_api-0.1.0/tests/e2e/test_threads/__init__.py +0 -0
  107. aegra_api-0.1.0/tests/e2e/test_threads/test_get_state_endpoint.py +168 -0
  108. aegra_api-0.1.0/tests/e2e/test_threads/test_history_endpoint.py +59 -0
  109. aegra_api-0.1.0/tests/e2e/test_threads/test_state_endpoint.py +78 -0
  110. aegra_api-0.1.0/tests/e2e/test_threads/test_thread_deletion.py +193 -0
  111. aegra_api-0.1.0/tests/e2e/test_threads/test_update_state_endpoint.py +454 -0
  112. aegra_api-0.1.0/tests/fixtures/__init__.py +1 -0
  113. aegra_api-0.1.0/tests/fixtures/auth.py +15 -0
  114. aegra_api-0.1.0/tests/fixtures/clients.py +40 -0
  115. aegra_api-0.1.0/tests/fixtures/custom_routes_with_auth.py +63 -0
  116. aegra_api-0.1.0/tests/fixtures/database.py +48 -0
  117. aegra_api-0.1.0/tests/fixtures/langgraph.py +179 -0
  118. aegra_api-0.1.0/tests/fixtures/mock_jwt_auth.py +133 -0
  119. aegra_api-0.1.0/tests/fixtures/session_fixtures.py +77 -0
  120. aegra_api-0.1.0/tests/fixtures/test_helpers.py +124 -0
  121. aegra_api-0.1.0/tests/integration/__init__.py +0 -0
  122. aegra_api-0.1.0/tests/integration/conftest.py +7 -0
  123. aegra_api-0.1.0/tests/integration/test_api/__init__.py +0 -0
  124. aegra_api-0.1.0/tests/integration/test_api/test_assistants_crud.py +737 -0
  125. aegra_api-0.1.0/tests/integration/test_api/test_runs_crud.py +790 -0
  126. aegra_api-0.1.0/tests/integration/test_api/test_store_crud.py +522 -0
  127. aegra_api-0.1.0/tests/integration/test_api/test_threads_crud.py +858 -0
  128. aegra_api-0.1.0/tests/integration/test_api/test_threads_history.py +202 -0
  129. aegra_api-0.1.0/tests/integration/test_auth_flow.py +350 -0
  130. aegra_api-0.1.0/tests/integration/test_auth_handlers_integration.py +175 -0
  131. aegra_api-0.1.0/tests/integration/test_cancel_run.py +189 -0
  132. aegra_api-0.1.0/tests/integration/test_custom_routes.py +209 -0
  133. aegra_api-0.1.0/tests/integration/test_services/__init__.py +0 -0
  134. aegra_api-0.1.0/tests/integration/test_services/test_assistant_service_db.py +460 -0
  135. aegra_api-0.1.0/tests/integration/test_services/test_event_store_integration.py +443 -0
  136. aegra_api-0.1.0/tests/integration/test_services/test_langgraph_service_integration.py +446 -0
  137. aegra_api-0.1.0/tests/integration/test_services/test_streaming_hitl.py +100 -0
  138. aegra_api-0.1.0/tests/integration/test_streaming_errors.py +303 -0
  139. aegra_api-0.1.0/tests/unit/__init__.py +0 -0
  140. aegra_api-0.1.0/tests/unit/conftest.py +23 -0
  141. aegra_api-0.1.0/tests/unit/test_api/test_runs.py +347 -0
  142. aegra_api-0.1.0/tests/unit/test_api/test_runs_streaming.py +218 -0
  143. aegra_api-0.1.0/tests/unit/test_api/test_runs_wait.py +744 -0
  144. aegra_api-0.1.0/tests/unit/test_api/test_thread_status.py +59 -0
  145. aegra_api-0.1.0/tests/unit/test_core/__init__.py +0 -0
  146. aegra_api-0.1.0/tests/unit/test_core/test_app_loader.py +91 -0
  147. aegra_api-0.1.0/tests/unit/test_core/test_auth_ctx.py +169 -0
  148. aegra_api-0.1.0/tests/unit/test_core/test_auth_deps.py +239 -0
  149. aegra_api-0.1.0/tests/unit/test_core/test_auth_handlers.py +426 -0
  150. aegra_api-0.1.0/tests/unit/test_core/test_auth_middleware.py +526 -0
  151. aegra_api-0.1.0/tests/unit/test_core/test_config.py +202 -0
  152. aegra_api-0.1.0/tests/unit/test_core/test_database_manager.py +228 -0
  153. aegra_api-0.1.0/tests/unit/test_core/test_route_merger.py +106 -0
  154. aegra_api-0.1.0/tests/unit/test_core/test_serializers/__init__.py +0 -0
  155. aegra_api-0.1.0/tests/unit/test_core/test_serializers/test_general.py +408 -0
  156. aegra_api-0.1.0/tests/unit/test_core/test_sse.py +294 -0
  157. aegra_api-0.1.0/tests/unit/test_cors_config.py +196 -0
  158. aegra_api-0.1.0/tests/unit/test_main.py +113 -0
  159. aegra_api-0.1.0/tests/unit/test_middleware/__init__.py +0 -0
  160. aegra_api-0.1.0/tests/unit/test_middleware/test_double_encoded_json.py +389 -0
  161. aegra_api-0.1.0/tests/unit/test_middleware/test_logger_middleware.py +112 -0
  162. aegra_api-0.1.0/tests/unit/test_models/__init__.py +0 -0
  163. aegra_api-0.1.0/tests/unit/test_models/test_run_status_validation.py +85 -0
  164. aegra_api-0.1.0/tests/unit/test_models/test_runcreate_validation.py +24 -0
  165. aegra_api-0.1.0/tests/unit/test_models/test_thread_status_validation.py +85 -0
  166. aegra_api-0.1.0/tests/unit/test_observability/__init__.py +0 -0
  167. aegra_api-0.1.0/tests/unit/test_observability/test_base.py +288 -0
  168. aegra_api-0.1.0/tests/unit/test_observability/test_otel.py +272 -0
  169. aegra_api-0.1.0/tests/unit/test_observability/test_setup.py +78 -0
  170. aegra_api-0.1.0/tests/unit/test_observability/test_targets/__init__.py +0 -0
  171. aegra_api-0.1.0/tests/unit/test_observability/test_targets/test_base.py +51 -0
  172. aegra_api-0.1.0/tests/unit/test_observability/test_targets/test_langfuse.py +72 -0
  173. aegra_api-0.1.0/tests/unit/test_observability/test_targets/test_otlp.py +84 -0
  174. aegra_api-0.1.0/tests/unit/test_observability/test_targets/test_phoenix.py +54 -0
  175. aegra_api-0.1.0/tests/unit/test_services/__init__.py +0 -0
  176. aegra_api-0.1.0/tests/unit/test_services/test_assistant_service.py +1021 -0
  177. aegra_api-0.1.0/tests/unit/test_services/test_assistant_service_schemas.py +337 -0
  178. aegra_api-0.1.0/tests/unit/test_services/test_broker.py +212 -0
  179. aegra_api-0.1.0/tests/unit/test_services/test_event_converter.py +351 -0
  180. aegra_api-0.1.0/tests/unit/test_services/test_event_converter_namespace.py +120 -0
  181. aegra_api-0.1.0/tests/unit/test_services/test_event_store.py +375 -0
  182. aegra_api-0.1.0/tests/unit/test_services/test_graph_streaming.py +719 -0
  183. aegra_api-0.1.0/tests/unit/test_services/test_graph_streaming_events_mode.py +138 -0
  184. aegra_api-0.1.0/tests/unit/test_services/test_langgraph_service.py +864 -0
  185. aegra_api-0.1.0/tests/unit/test_services/test_streaming_service.py +460 -0
  186. aegra_api-0.1.0/tests/unit/test_services/test_thread_state_service.py +130 -0
  187. aegra_api-0.1.0/tests/unit/test_threads/test_state.py +222 -0
  188. aegra_api-0.1.0/tests/unit/test_threads/test_state_checkpoint.py +274 -0
  189. aegra_api-0.1.0/tests/unit/test_utils/__init__.py +0 -0
  190. aegra_api-0.1.0/tests/unit/test_utils/test_assistants_utils.py +101 -0
  191. aegra_api-0.1.0/tests/unit/test_utils/test_run_utils.py +83 -0
  192. aegra_api-0.1.0/tests/unit/test_utils/test_sse_utils.py +135 -0
  193. aegra_api-0.1.0/tests/unit/test_utils/test_status_compat.py +52 -0
  194. aegra_api-0.1.0/uv.lock +2555 -0
@@ -0,0 +1,32 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+
12
+ # env files
13
+ .env
14
+
15
+ # Pycharm
16
+ .idea/
17
+
18
+ # VSCode
19
+ .vscode/
20
+
21
+ # Testing
22
+ .coverage
23
+ coverage.xml
24
+ htmlcov/
25
+ .pytest_cache/
26
+ .mypy_cache/
27
+
28
+ # Ruff
29
+ .ruff_cache/
30
+
31
+ # Pre-commit
32
+ .pre-commit-cache/
@@ -0,0 +1,244 @@
1
+ Metadata-Version: 2.4
2
+ Name: aegra-api
3
+ Version: 0.1.0
4
+ Summary: Aegra core API - Self-hosted Agent Protocol server
5
+ Project-URL: Homepage, https://github.com/ibbybuilds/aegra
6
+ Project-URL: Documentation, https://github.com/ibbybuilds/aegra#readme
7
+ Project-URL: Repository, https://github.com/ibbybuilds/aegra
8
+ Project-URL: Issues, https://github.com/ibbybuilds/aegra/issues
9
+ Author-email: Muhammad Ibrahim <mibrahim37612@gmail.com>
10
+ License-Expression: Apache-2.0
11
+ Keywords: agent-protocol,agents,fastapi,langgraph,llm
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Framework :: FastAPI
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: Apache Software License
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Requires-Python: >=3.11
20
+ Requires-Dist: alembic>=1.16.4
21
+ Requires-Dist: asgi-correlation-id>=4.3.4
22
+ Requires-Dist: asyncpg>=0.30.0
23
+ Requires-Dist: fastapi>=0.116.1
24
+ Requires-Dist: greenlet>=3.2.3
25
+ Requires-Dist: langchain-openai>=1.0.3
26
+ Requires-Dist: langchain>=1.0.8
27
+ Requires-Dist: langgraph-checkpoint-postgres>=2.0.23
28
+ Requires-Dist: langgraph>=1.0.3
29
+ Requires-Dist: openinference-instrumentation-langchain>=0.1.58
30
+ Requires-Dist: opentelemetry-api>=1.39.1
31
+ Requires-Dist: opentelemetry-exporter-otlp>=1.39.1
32
+ Requires-Dist: opentelemetry-sdk>=1.39.1
33
+ Requires-Dist: psycopg[binary]>=3.2.9
34
+ Requires-Dist: pydantic-settings>=2.12.0
35
+ Requires-Dist: pydantic>=2.11.7
36
+ Requires-Dist: pyjwt>=2.10.1
37
+ Requires-Dist: python-dotenv>=1.1.1
38
+ Requires-Dist: sqlalchemy>=2.0.0
39
+ Requires-Dist: structlog>=25.4.0
40
+ Requires-Dist: uvicorn>=0.35.0
41
+ Description-Content-Type: text/markdown
42
+
43
+ # aegra-api
44
+
45
+ Aegra API - Self-hosted Agent Protocol server.
46
+
47
+ Aegra is an open-source, self-hosted alternative to LangGraph Platform. This package provides the core API server that implements the Agent Protocol, allowing you to run AI agents on your own infrastructure without vendor lock-in.
48
+
49
+ ## Features
50
+
51
+ - **Agent Protocol Compliant**: Works with Agent Chat UI, LangGraph Studio, CopilotKit
52
+ - **Drop-in Replacement**: Compatible with the LangGraph SDK
53
+ - **Self-Hosted**: Run on your own PostgreSQL database
54
+ - **Streaming Support**: Real-time streaming of agent responses
55
+ - **Human-in-the-Loop**: Built-in support for human approval workflows
56
+ - **Vector Store**: Semantic search capabilities with PostgreSQL
57
+
58
+ ## Installation
59
+
60
+ ```bash
61
+ pip install aegra-api
62
+ ```
63
+
64
+ ## Quick Start
65
+
66
+ The easiest way to get started is with the [aegra-cli](../aegra-cli/README.md):
67
+
68
+ ```bash
69
+ # Install the CLI
70
+ pip install aegra-cli
71
+
72
+ # Initialize a new project
73
+ aegra init --docker
74
+
75
+ # Start services
76
+ aegra up
77
+
78
+ # Apply migrations
79
+ aegra db upgrade
80
+
81
+ # Start development server
82
+ aegra dev
83
+ ```
84
+
85
+ ### Manual Setup
86
+
87
+ If you prefer manual setup:
88
+
89
+ ```bash
90
+ # Install dependencies
91
+ pip install aegra-api
92
+
93
+ # Set environment variables
94
+ export POSTGRES_USER=aegra
95
+ export POSTGRES_PASSWORD=aegra_secret
96
+ export POSTGRES_HOST=localhost
97
+ export POSTGRES_DB=aegra
98
+
99
+ # Run migrations
100
+ alembic upgrade head
101
+
102
+ # Start server
103
+ uvicorn aegra_api.main:app --reload
104
+ ```
105
+
106
+ ## Configuration
107
+
108
+ ### aegra.json
109
+
110
+ Define your agent graphs in `aegra.json`:
111
+
112
+ ```json
113
+ {
114
+ "graphs": {
115
+ "agent": "./graphs/my_agent/graph.py:graph",
116
+ "assistant": "./graphs/assistant/graph.py:graph"
117
+ },
118
+ "http": {
119
+ "app": "./custom_routes.py:app"
120
+ }
121
+ }
122
+ ```
123
+
124
+ ### Environment Variables
125
+
126
+ ```bash
127
+ # Database
128
+ POSTGRES_USER=aegra
129
+ POSTGRES_PASSWORD=aegra_secret
130
+ POSTGRES_HOST=localhost
131
+ POSTGRES_DB=aegra
132
+
133
+ # Authentication
134
+ AUTH_TYPE=noop # Options: noop, custom
135
+
136
+ # Server
137
+ HOST=0.0.0.0
138
+ PORT=8000
139
+
140
+ # Configuration
141
+ AEGRA_CONFIG=aegra.json
142
+
143
+ # LLM (for example agents)
144
+ OPENAI_API_KEY=sk-...
145
+
146
+ # Observability (optional)
147
+ OTEL_TARGETS=LANGFUSE,PHOENIX
148
+ ```
149
+
150
+ ## API Endpoints
151
+
152
+ | Endpoint | Method | Description |
153
+ |----------|--------|-------------|
154
+ | `/assistants` | POST | Create assistant from graph_id |
155
+ | `/assistants` | GET | List user's assistants |
156
+ | `/assistants/{id}` | GET | Get assistant details |
157
+ | `/threads` | POST | Create conversation thread |
158
+ | `/threads/{id}/state` | GET | Get thread state |
159
+ | `/threads/{id}/runs` | POST | Execute graph (streaming/background) |
160
+ | `/runs/{id}/stream` | POST | Stream run events |
161
+ | `/store` | PUT | Save to vector store |
162
+ | `/store/search` | POST | Semantic search |
163
+ | `/health` | GET | Health check |
164
+
165
+ ## Creating Graphs
166
+
167
+ Agents are Python modules exporting a compiled `graph` variable:
168
+
169
+ ```python
170
+ # graphs/my_agent/graph.py
171
+ from typing import TypedDict
172
+ from langgraph.graph import StateGraph, START, END
173
+
174
+ class State(TypedDict):
175
+ messages: list[str]
176
+
177
+ def process_node(state: State) -> State:
178
+ messages = state.get("messages", [])
179
+ messages.append("Processed!")
180
+ return {"messages": messages}
181
+
182
+ # Build the graph
183
+ builder = StateGraph(State)
184
+ builder.add_node("process", process_node)
185
+ builder.add_edge(START, "process")
186
+ builder.add_edge("process", END)
187
+
188
+ # Export as 'graph'
189
+ graph = builder.compile()
190
+ ```
191
+
192
+ ## Architecture
193
+
194
+ ```
195
+ +---------------------------------------------------------+
196
+ | FastAPI HTTP Layer (Agent Protocol API) |
197
+ | - /assistants, /threads, /runs, /store endpoints |
198
+ +---------------------------------------------------------+
199
+ | Middleware Stack |
200
+ | - Auth, CORS, Structured Logging, Correlation ID |
201
+ +---------------------------------------------------------+
202
+ | Service Layer (Business Logic) |
203
+ | - LangGraphService, AssistantService, StreamingService |
204
+ +---------------------------------------------------------+
205
+ | LangGraph Runtime |
206
+ | - Graph execution, state management, tool execution |
207
+ +---------------------------------------------------------+
208
+ | Database Layer (PostgreSQL) |
209
+ | - AsyncPostgresSaver (checkpoints), AsyncPostgresStore |
210
+ +---------------------------------------------------------+
211
+ ```
212
+
213
+ ## Package Structure
214
+
215
+ ```
216
+ libs/aegra-api/
217
+ ├── src/aegra_api/
218
+ │ ├── api/ # Agent Protocol endpoints
219
+ │ │ ├── assistants.py # /assistants CRUD
220
+ │ │ ├── threads.py # /threads and state management
221
+ │ │ ├── runs.py # /runs execution and streaming
222
+ │ │ └── store.py # /store vector storage
223
+ │ ├── services/ # Business logic layer
224
+ │ ├── core/ # Infrastructure (database, auth, orm)
225
+ │ ├── models/ # Pydantic request/response schemas
226
+ │ ├── middleware/ # ASGI middleware
227
+ │ ├── observability/ # OpenTelemetry tracing
228
+ │ ├── utils/ # Helper functions
229
+ │ ├── main.py # FastAPI app entry point
230
+ │ ├── config.py # HTTP/store config loading
231
+ │ └── settings.py # Environment settings
232
+ ├── tests/ # Test suite
233
+ ├── alembic/ # Database migrations
234
+ └── pyproject.toml
235
+ ```
236
+
237
+ ## Related Packages
238
+
239
+ - **aegra-cli**: Command-line interface for project management
240
+ - **aegra**: Meta-package that installs both aegra-api and aegra-cli
241
+
242
+ ## Documentation
243
+
244
+ For full documentation, see the [CLAUDE.md](../../CLAUDE.md) file in the repository root.
@@ -0,0 +1,202 @@
1
+ # aegra-api
2
+
3
+ Aegra API - Self-hosted Agent Protocol server.
4
+
5
+ Aegra is an open-source, self-hosted alternative to LangGraph Platform. This package provides the core API server that implements the Agent Protocol, allowing you to run AI agents on your own infrastructure without vendor lock-in.
6
+
7
+ ## Features
8
+
9
+ - **Agent Protocol Compliant**: Works with Agent Chat UI, LangGraph Studio, CopilotKit
10
+ - **Drop-in Replacement**: Compatible with the LangGraph SDK
11
+ - **Self-Hosted**: Run on your own PostgreSQL database
12
+ - **Streaming Support**: Real-time streaming of agent responses
13
+ - **Human-in-the-Loop**: Built-in support for human approval workflows
14
+ - **Vector Store**: Semantic search capabilities with PostgreSQL
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ pip install aegra-api
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ The easiest way to get started is with the [aegra-cli](../aegra-cli/README.md):
25
+
26
+ ```bash
27
+ # Install the CLI
28
+ pip install aegra-cli
29
+
30
+ # Initialize a new project
31
+ aegra init --docker
32
+
33
+ # Start services
34
+ aegra up
35
+
36
+ # Apply migrations
37
+ aegra db upgrade
38
+
39
+ # Start development server
40
+ aegra dev
41
+ ```
42
+
43
+ ### Manual Setup
44
+
45
+ If you prefer manual setup:
46
+
47
+ ```bash
48
+ # Install dependencies
49
+ pip install aegra-api
50
+
51
+ # Set environment variables
52
+ export POSTGRES_USER=aegra
53
+ export POSTGRES_PASSWORD=aegra_secret
54
+ export POSTGRES_HOST=localhost
55
+ export POSTGRES_DB=aegra
56
+
57
+ # Run migrations
58
+ alembic upgrade head
59
+
60
+ # Start server
61
+ uvicorn aegra_api.main:app --reload
62
+ ```
63
+
64
+ ## Configuration
65
+
66
+ ### aegra.json
67
+
68
+ Define your agent graphs in `aegra.json`:
69
+
70
+ ```json
71
+ {
72
+ "graphs": {
73
+ "agent": "./graphs/my_agent/graph.py:graph",
74
+ "assistant": "./graphs/assistant/graph.py:graph"
75
+ },
76
+ "http": {
77
+ "app": "./custom_routes.py:app"
78
+ }
79
+ }
80
+ ```
81
+
82
+ ### Environment Variables
83
+
84
+ ```bash
85
+ # Database
86
+ POSTGRES_USER=aegra
87
+ POSTGRES_PASSWORD=aegra_secret
88
+ POSTGRES_HOST=localhost
89
+ POSTGRES_DB=aegra
90
+
91
+ # Authentication
92
+ AUTH_TYPE=noop # Options: noop, custom
93
+
94
+ # Server
95
+ HOST=0.0.0.0
96
+ PORT=8000
97
+
98
+ # Configuration
99
+ AEGRA_CONFIG=aegra.json
100
+
101
+ # LLM (for example agents)
102
+ OPENAI_API_KEY=sk-...
103
+
104
+ # Observability (optional)
105
+ OTEL_TARGETS=LANGFUSE,PHOENIX
106
+ ```
107
+
108
+ ## API Endpoints
109
+
110
+ | Endpoint | Method | Description |
111
+ |----------|--------|-------------|
112
+ | `/assistants` | POST | Create assistant from graph_id |
113
+ | `/assistants` | GET | List user's assistants |
114
+ | `/assistants/{id}` | GET | Get assistant details |
115
+ | `/threads` | POST | Create conversation thread |
116
+ | `/threads/{id}/state` | GET | Get thread state |
117
+ | `/threads/{id}/runs` | POST | Execute graph (streaming/background) |
118
+ | `/runs/{id}/stream` | POST | Stream run events |
119
+ | `/store` | PUT | Save to vector store |
120
+ | `/store/search` | POST | Semantic search |
121
+ | `/health` | GET | Health check |
122
+
123
+ ## Creating Graphs
124
+
125
+ Agents are Python modules exporting a compiled `graph` variable:
126
+
127
+ ```python
128
+ # graphs/my_agent/graph.py
129
+ from typing import TypedDict
130
+ from langgraph.graph import StateGraph, START, END
131
+
132
+ class State(TypedDict):
133
+ messages: list[str]
134
+
135
+ def process_node(state: State) -> State:
136
+ messages = state.get("messages", [])
137
+ messages.append("Processed!")
138
+ return {"messages": messages}
139
+
140
+ # Build the graph
141
+ builder = StateGraph(State)
142
+ builder.add_node("process", process_node)
143
+ builder.add_edge(START, "process")
144
+ builder.add_edge("process", END)
145
+
146
+ # Export as 'graph'
147
+ graph = builder.compile()
148
+ ```
149
+
150
+ ## Architecture
151
+
152
+ ```
153
+ +---------------------------------------------------------+
154
+ | FastAPI HTTP Layer (Agent Protocol API) |
155
+ | - /assistants, /threads, /runs, /store endpoints |
156
+ +---------------------------------------------------------+
157
+ | Middleware Stack |
158
+ | - Auth, CORS, Structured Logging, Correlation ID |
159
+ +---------------------------------------------------------+
160
+ | Service Layer (Business Logic) |
161
+ | - LangGraphService, AssistantService, StreamingService |
162
+ +---------------------------------------------------------+
163
+ | LangGraph Runtime |
164
+ | - Graph execution, state management, tool execution |
165
+ +---------------------------------------------------------+
166
+ | Database Layer (PostgreSQL) |
167
+ | - AsyncPostgresSaver (checkpoints), AsyncPostgresStore |
168
+ +---------------------------------------------------------+
169
+ ```
170
+
171
+ ## Package Structure
172
+
173
+ ```
174
+ libs/aegra-api/
175
+ ├── src/aegra_api/
176
+ │ ├── api/ # Agent Protocol endpoints
177
+ │ │ ├── assistants.py # /assistants CRUD
178
+ │ │ ├── threads.py # /threads and state management
179
+ │ │ ├── runs.py # /runs execution and streaming
180
+ │ │ └── store.py # /store vector storage
181
+ │ ├── services/ # Business logic layer
182
+ │ ├── core/ # Infrastructure (database, auth, orm)
183
+ │ ├── models/ # Pydantic request/response schemas
184
+ │ ├── middleware/ # ASGI middleware
185
+ │ ├── observability/ # OpenTelemetry tracing
186
+ │ ├── utils/ # Helper functions
187
+ │ ├── main.py # FastAPI app entry point
188
+ │ ├── config.py # HTTP/store config loading
189
+ │ └── settings.py # Environment settings
190
+ ├── tests/ # Test suite
191
+ ├── alembic/ # Database migrations
192
+ └── pyproject.toml
193
+ ```
194
+
195
+ ## Related Packages
196
+
197
+ - **aegra-cli**: Command-line interface for project management
198
+ - **aegra**: Meta-package that installs both aegra-api and aegra-cli
199
+
200
+ ## Documentation
201
+
202
+ For full documentation, see the [CLAUDE.md](../../CLAUDE.md) file in the repository root.
@@ -0,0 +1,100 @@
1
+ """Alembic environment configuration for Aegra database migrations."""
2
+
3
+ import asyncio
4
+ from logging.config import fileConfig
5
+
6
+ from sqlalchemy import pool
7
+ from sqlalchemy.engine import Connection
8
+ from sqlalchemy.ext.asyncio import async_engine_from_config
9
+
10
+ # Import your SQLAlchemy models here
11
+ from aegra_api.core.orm import Base
12
+ from aegra_api.settings import settings
13
+ from alembic import context
14
+
15
+ # This is the Alembic Config object, which provides
16
+ # access to the values within the .ini file in use.
17
+ config = context.config
18
+
19
+ section = config.config_ini_section
20
+ config.set_section_option(section, "DB_HOST", settings.db.POSTGRES_HOST)
21
+ config.set_section_option(section, "DB_PORT", settings.db.POSTGRES_PORT)
22
+ config.set_section_option(section, "DB_USER", settings.db.POSTGRES_USER)
23
+ config.set_section_option(section, "DB_NAME", settings.db.POSTGRES_DB)
24
+ config.set_section_option(section, "DB_PASS", settings.db.POSTGRES_PASSWORD)
25
+
26
+ # Interpret the config file for Python logging.
27
+ # This line sets up loggers basically.
28
+ if config.config_file_name is not None:
29
+ fileConfig(config.config_file_name)
30
+
31
+ # add your model's MetaData object here
32
+ # for 'autogenerate' support
33
+ target_metadata = Base.metadata
34
+
35
+ # other values from the config, defined by the needs of env.py,
36
+ # can be acquired:
37
+ # my_important_option = config.get_main_option("my_important_option")
38
+ # ... etc.
39
+
40
+
41
+ def run_migrations_offline() -> None:
42
+ """Run migrations in 'offline' mode.
43
+
44
+ This configures the context with just a URL
45
+ and not an Engine, though an Engine is acceptable
46
+ here as well. By skipping the Engine creation
47
+ we don't even need a DBAPI to be available.
48
+
49
+ Calls to context.execute() here emit the given string to the
50
+ script output.
51
+
52
+ """
53
+ context.configure(
54
+ url=config.get_main_option("sqlalchemy.url"),
55
+ target_metadata=target_metadata,
56
+ literal_binds=True,
57
+ dialect_opts={"paramstyle": "named"},
58
+ )
59
+
60
+ with context.begin_transaction():
61
+ context.run_migrations()
62
+
63
+
64
+ def do_run_migrations(connection: Connection) -> None:
65
+ """Run migrations with the given connection."""
66
+ context.configure(connection=connection, target_metadata=target_metadata)
67
+
68
+ with context.begin_transaction():
69
+ context.run_migrations()
70
+
71
+
72
+ async def run_async_migrations() -> None:
73
+ """In this scenario we need to create an Engine
74
+ and associate a connection with the context.
75
+
76
+ """
77
+ configuration = config.get_section(config.config_ini_section)
78
+ configuration["sqlalchemy.url"] = config.get_main_option("sqlalchemy.url")
79
+
80
+ connectable = async_engine_from_config(
81
+ configuration,
82
+ prefix="sqlalchemy.",
83
+ poolclass=pool.NullPool,
84
+ )
85
+
86
+ async with connectable.connect() as connection:
87
+ await connection.run_sync(do_run_migrations)
88
+
89
+ await connectable.dispose()
90
+
91
+
92
+ def run_migrations_online() -> None:
93
+ """Run migrations in 'online' mode."""
94
+ asyncio.run(run_async_migrations())
95
+
96
+
97
+ if context.is_offline_mode():
98
+ run_migrations_offline()
99
+ else:
100
+ run_migrations_online()
@@ -0,0 +1,24 @@
1
+ """${message}
2
+
3
+ Revision ID: ${up_revision}
4
+ Revises: ${down_revision | comma,n}
5
+ Create Date: ${create_date}
6
+
7
+ """
8
+ from alembic import op
9
+ import sqlalchemy as sa
10
+ ${imports if imports else ""}
11
+
12
+ # revision identifiers, used by Alembic.
13
+ revision = ${repr(up_revision)}
14
+ down_revision = ${repr(down_revision)}
15
+ branch_labels = ${repr(branch_labels)}
16
+ depends_on = ${repr(depends_on)}
17
+
18
+
19
+ def upgrade() -> None:
20
+ ${upgrades if upgrades else "pass"}
21
+
22
+
23
+ def downgrade() -> None:
24
+ ${downgrades if downgrades else "pass"}