aegra-api 0.1.0__py3-none-any.whl

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 (64) hide show
  1. aegra_api/__init__.py +3 -0
  2. aegra_api/api/__init__.py +1 -0
  3. aegra_api/api/assistants.py +235 -0
  4. aegra_api/api/runs.py +1110 -0
  5. aegra_api/api/store.py +200 -0
  6. aegra_api/api/threads.py +761 -0
  7. aegra_api/config.py +204 -0
  8. aegra_api/constants.py +5 -0
  9. aegra_api/core/__init__.py +0 -0
  10. aegra_api/core/app_loader.py +91 -0
  11. aegra_api/core/auth_ctx.py +65 -0
  12. aegra_api/core/auth_deps.py +186 -0
  13. aegra_api/core/auth_handlers.py +248 -0
  14. aegra_api/core/auth_middleware.py +331 -0
  15. aegra_api/core/database.py +123 -0
  16. aegra_api/core/health.py +131 -0
  17. aegra_api/core/orm.py +165 -0
  18. aegra_api/core/route_merger.py +69 -0
  19. aegra_api/core/serializers/__init__.py +7 -0
  20. aegra_api/core/serializers/base.py +22 -0
  21. aegra_api/core/serializers/general.py +54 -0
  22. aegra_api/core/serializers/langgraph.py +102 -0
  23. aegra_api/core/sse.py +178 -0
  24. aegra_api/main.py +303 -0
  25. aegra_api/middleware/__init__.py +4 -0
  26. aegra_api/middleware/double_encoded_json.py +74 -0
  27. aegra_api/middleware/logger_middleware.py +95 -0
  28. aegra_api/models/__init__.py +76 -0
  29. aegra_api/models/assistants.py +81 -0
  30. aegra_api/models/auth.py +62 -0
  31. aegra_api/models/enums.py +29 -0
  32. aegra_api/models/errors.py +29 -0
  33. aegra_api/models/runs.py +124 -0
  34. aegra_api/models/store.py +67 -0
  35. aegra_api/models/threads.py +152 -0
  36. aegra_api/observability/__init__.py +1 -0
  37. aegra_api/observability/base.py +88 -0
  38. aegra_api/observability/otel.py +133 -0
  39. aegra_api/observability/setup.py +27 -0
  40. aegra_api/observability/targets/__init__.py +11 -0
  41. aegra_api/observability/targets/base.py +18 -0
  42. aegra_api/observability/targets/langfuse.py +33 -0
  43. aegra_api/observability/targets/otlp.py +38 -0
  44. aegra_api/observability/targets/phoenix.py +24 -0
  45. aegra_api/services/__init__.py +0 -0
  46. aegra_api/services/assistant_service.py +569 -0
  47. aegra_api/services/base_broker.py +59 -0
  48. aegra_api/services/broker.py +141 -0
  49. aegra_api/services/event_converter.py +157 -0
  50. aegra_api/services/event_store.py +196 -0
  51. aegra_api/services/graph_streaming.py +433 -0
  52. aegra_api/services/langgraph_service.py +456 -0
  53. aegra_api/services/streaming_service.py +362 -0
  54. aegra_api/services/thread_state_service.py +128 -0
  55. aegra_api/settings.py +124 -0
  56. aegra_api/utils/__init__.py +3 -0
  57. aegra_api/utils/assistants.py +23 -0
  58. aegra_api/utils/run_utils.py +60 -0
  59. aegra_api/utils/setup_logging.py +122 -0
  60. aegra_api/utils/sse_utils.py +26 -0
  61. aegra_api/utils/status_compat.py +57 -0
  62. aegra_api-0.1.0.dist-info/METADATA +244 -0
  63. aegra_api-0.1.0.dist-info/RECORD +64 -0
  64. aegra_api-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,60 @@
1
+ import copy
2
+ from typing import Any
3
+
4
+ import structlog
5
+
6
+ logger = structlog.getLogger(__name__)
7
+
8
+
9
+ def _should_skip_event(raw_event: Any) -> bool:
10
+ """Check if an event should be skipped based on langsmith:nostream tag"""
11
+ try:
12
+ # Check if the event has metadata with tags containing 'langsmith:nostream'
13
+ if isinstance(raw_event, tuple) and len(raw_event) >= 2:
14
+ # For tuple events, check the third element (metadata tuple)
15
+ metadata_tuple = raw_event[len(raw_event) - 1]
16
+ if isinstance(metadata_tuple, tuple) and len(metadata_tuple) >= 2:
17
+ # Get the second item in the metadata tuple
18
+ metadata = metadata_tuple[1]
19
+ if isinstance(metadata, dict) and "tags" in metadata:
20
+ tags = metadata["tags"]
21
+ if isinstance(tags, list) and "langsmith:nostream" in tags:
22
+ return True
23
+ return False
24
+ except Exception:
25
+ # If we can't parse the event structure, don't skip it
26
+ return False
27
+
28
+
29
+ def _merge_jsonb(*objects: dict) -> dict:
30
+ """Mimics PostgreSQL's JSONB merge behavior"""
31
+ result = {}
32
+ for obj in objects:
33
+ if obj is not None:
34
+ result.update(copy.deepcopy(obj))
35
+ return result
36
+
37
+
38
+ async def _filter_context_by_schema(context: dict[str, Any], context_schema: dict | None) -> dict[str, Any]:
39
+ """Filter context parameters based on the context schema."""
40
+ if not context_schema or not context:
41
+ return context
42
+
43
+ # Extract valid properties from the schema
44
+ properties = context_schema.get("properties", {})
45
+ if not properties:
46
+ return context
47
+
48
+ # Filter context to only include parameters defined in the schema
49
+ filtered_context = {}
50
+ for key, value in context.items():
51
+ if key in properties:
52
+ filtered_context[key] = value
53
+ else:
54
+ await logger.adebug(
55
+ f"Filtering out context parameter '{key}' not found in context schema",
56
+ context_key=key,
57
+ available_keys=list(properties.keys()),
58
+ )
59
+
60
+ return filtered_context
@@ -0,0 +1,122 @@
1
+ import logging
2
+ import logging.config
3
+ from typing import Any
4
+
5
+ import structlog
6
+
7
+ from aegra_api.settings import settings
8
+
9
+
10
+ def get_logging_config() -> dict[str, Any]:
11
+ """
12
+ Returns a unified logging configuration dictionary that uses structlog
13
+ for consistent, structured logging across the application and Uvicorn.
14
+
15
+ This configuration solves the multiprocessing "pickling" error on Windows
16
+ by using string references for streams (e.g., "ext://sys.stdout").
17
+ """
18
+ # Determine log level from environment or set a default
19
+ env_mode = settings.app.ENV_MODE
20
+ log_level = settings.app.LOG_LEVEL
21
+
22
+ # These processors will be used by BOTH structlog and standard logging
23
+ # to ensure consistent output for all logs.
24
+ shared_processors: list[Any] = [
25
+ structlog.stdlib.add_log_level,
26
+ structlog.stdlib.add_logger_name,
27
+ structlog.processors.CallsiteParameterAdder(
28
+ {
29
+ structlog.processors.CallsiteParameter.FILENAME,
30
+ structlog.processors.CallsiteParameter.FUNC_NAME,
31
+ structlog.processors.CallsiteParameter.LINENO,
32
+ }
33
+ ),
34
+ structlog.processors.TimeStamper(fmt="iso"),
35
+ # This processor must be last in the shared chain to format positional args.
36
+ structlog.stdlib.PositionalArgumentsFormatter(),
37
+ ]
38
+
39
+ # Determine the final renderer based on the environment
40
+ # Use a colorful console renderer for local development, and JSON for production.
41
+ if env_mode in ("LOCAL", "DEVELOPMENT"):
42
+ final_renderer = structlog.dev.ConsoleRenderer(colors=True, pad_level=True)
43
+ else:
44
+ final_renderer = structlog.processors.JSONRenderer()
45
+
46
+ return {
47
+ "version": 1,
48
+ "disable_existing_loggers": False, # Important for library logging
49
+ "formatters": {
50
+ "default": {
51
+ # Use structlog's formatter as the bridge
52
+ "()": "structlog.stdlib.ProcessorFormatter",
53
+ # The final processor is the renderer.
54
+ "processor": final_renderer,
55
+ # These processors are run on ANY log record, including those from Uvicorn.
56
+ "foreign_pre_chain": shared_processors,
57
+ },
58
+ },
59
+ "handlers": {
60
+ "default": {
61
+ "level": log_level,
62
+ "class": "logging.StreamHandler",
63
+ "formatter": "default",
64
+ # IMPORTANT: Use the string reference to avoid the pickling error.
65
+ # This defers the lookup of sys.stdout until the config is loaded
66
+ # in the child process.
67
+ "stream": "ext://sys.stdout",
68
+ },
69
+ },
70
+ "loggers": {
71
+ # Configure the root logger to catch everything
72
+ "": {
73
+ "handlers": ["default"],
74
+ "level": log_level,
75
+ "propagate": False, # Don't pass to other handlers
76
+ },
77
+ # Uvicorn's loggers will now inherit the root logger's settings,
78
+ # ensuring they use the same handler and formatter.
79
+ # We explicitly set their level here.
80
+ "uvicorn.error": {
81
+ "level": "INFO",
82
+ },
83
+ "uvicorn.access": {
84
+ "level": "WARNING",
85
+ },
86
+ },
87
+ }
88
+
89
+
90
+ def setup_logging():
91
+ """
92
+ Configures both standard logging and structlog based on the
93
+ dictionary from get_logging_config(). This should be called
94
+ once at application startup.
95
+ """
96
+ config = get_logging_config()
97
+
98
+ # Configure the standard logging module
99
+ logging.config.dictConfig(config)
100
+ # Propagate uvicorn logs instead of letting uvicorn configure the format
101
+ for name in ["uvicorn", "uvicorn.access", "uvicorn.error"]:
102
+ logging.getLogger(name).handlers.clear()
103
+ logging.getLogger(name).propagate = True
104
+
105
+ # Reconfigure log levels for some overly chatty libraries
106
+ logging.getLogger("uvicorn.access").setLevel(logging.WARNING)
107
+ logging.getLogger("urllib3.connectionpool").setLevel(logging.ERROR)
108
+
109
+ # Configure structlog to route its logs through the standard logging
110
+ # system that we just configured.
111
+ structlog.configure(
112
+ processors=[
113
+ structlog.stdlib.filter_by_level,
114
+ # Add shared processors to structlog's pipeline
115
+ *config["formatters"]["default"]["foreign_pre_chain"],
116
+ # Prepare the log record for the standard library's formatter
117
+ structlog.stdlib.ProcessorFormatter.wrap_for_formatter,
118
+ ],
119
+ logger_factory=structlog.stdlib.LoggerFactory(),
120
+ wrapper_class=structlog.stdlib.BoundLogger,
121
+ cache_logger_on_first_use=True,
122
+ )
@@ -0,0 +1,26 @@
1
+ def generate_event_id(run_id: str, sequence: int) -> str:
2
+ """Generate SSE event ID in the format: {run_id}_event_{sequence}
3
+
4
+ Args:
5
+ run_id: The run identifier
6
+ sequence: The event sequence number
7
+
8
+ Returns:
9
+ Formatted event ID string
10
+ """
11
+ return f"{run_id}_event_{sequence}"
12
+
13
+
14
+ def extract_event_sequence(event_id: str) -> int:
15
+ """Extract numeric sequence from event_id format: {run_id}_event_{sequence}
16
+
17
+ Args:
18
+ event_id: The event ID string
19
+
20
+ Returns:
21
+ The sequence number, or 0 if extraction fails
22
+ """
23
+ try:
24
+ return int(event_id.split("_event_")[-1])
25
+ except (ValueError, IndexError):
26
+ return 0
@@ -0,0 +1,57 @@
1
+ """Status validation utilities.
2
+
3
+ After migration, all database records have standard status values.
4
+ This module validates that statuses conform to the API specification.
5
+ """
6
+
7
+ from aegra_api.models.enums import RunStatus, ThreadStatus
8
+
9
+
10
+ def validate_run_status(status: str) -> RunStatus:
11
+ """Validate that run status conforms to API specification.
12
+
13
+ After migration, all statuses should be standard values.
14
+ This function validates and rejects any invalid statuses.
15
+
16
+ Args:
17
+ status: Status string to validate
18
+
19
+ Returns:
20
+ Validated RunStatus value
21
+
22
+ Raises:
23
+ ValueError: If status is not a valid RunStatus
24
+ """
25
+ valid_statuses: list[RunStatus] = [
26
+ "pending",
27
+ "running",
28
+ "error",
29
+ "success",
30
+ "timeout",
31
+ "interrupted",
32
+ ]
33
+
34
+ if status not in valid_statuses:
35
+ raise ValueError(f"Invalid run status: {status}. Must be one of: {valid_statuses}")
36
+
37
+ return status # type: ignore
38
+
39
+
40
+ def validate_thread_status(status: str) -> ThreadStatus:
41
+ """Validate that thread status conforms to API specification.
42
+
43
+ Args:
44
+ status: Thread status string to validate
45
+
46
+ Returns:
47
+ Validated ThreadStatus value
48
+
49
+ Raises:
50
+ ValueError: If status is not a valid ThreadStatus
51
+ """
52
+ valid_statuses: list[ThreadStatus] = ["idle", "busy", "interrupted", "error"]
53
+
54
+ if status not in valid_statuses:
55
+ raise ValueError(f"Invalid thread status: {status}. Must be one of: {valid_statuses}")
56
+
57
+ return status # type: ignore
@@ -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,64 @@
1
+ aegra_api/__init__.py,sha256=EJeLj3vj2Jga09BGNNPx-VcPRK-fUCLvTnkSeT3UntY,76
2
+ aegra_api/config.py,sha256=llBQGVeAnlERmqZE4_mW5mBr3dHWrtxrmdl-O4uMADc,5657
3
+ aegra_api/constants.py,sha256=64ESEhwXCYjug4AXc8bR46fHrQI7pI0L0paWet1ECCI,260
4
+ aegra_api/main.py,sha256=8JVRfsc20QrcJyiosP75aDepxSb9k5UgbKfW7VBEf1o,10905
5
+ aegra_api/settings.py,sha256=eOQkyjgw4aJEwMn1FN_V7p4kcI9iv7NOlq5cEpjREvo,3487
6
+ aegra_api/api/__init__.py,sha256=W-8xMdTikfj8XRYLwnyjy2I54FoCCOXplhJPrARSi00,35
7
+ aegra_api/api/assistants.py,sha256=vnO-lDNjioqBiiwOIYCgToKZMX-iLKX7k6VjlR3IFxc,8231
8
+ aegra_api/api/runs.py,sha256=ikLSKwh3spEtw1nCwqRZ5aoy1N-TOrsY-soPnkXJevQ,42652
9
+ aegra_api/api/store.py,sha256=YbVWuasUJo2aoOSr-kPDK4a1vJrmAqBATe7yScU_6bI,6314
10
+ aegra_api/api/threads.py,sha256=98Y8hrzh1pZToeWcC0eCeZBg6VAvKCq9tXxKCptPzwY,28712
11
+ aegra_api/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ aegra_api/core/app_loader.py,sha256=mnVDWdNF140TFrW6mm3NZjIArHXJd1mIbNQ5rPEHBSk,3463
13
+ aegra_api/core/auth_ctx.py,sha256=bG5RhMFaglQglOVRIu5cWo9ybPfSwV4_lBTumBiQjmo,2188
14
+ aegra_api/core/auth_deps.py,sha256=1z-p54Av_XSlDh3HA02k4glCUXZOqLbK3wGxP6hqpys,5775
15
+ aegra_api/core/auth_handlers.py,sha256=tAyqqj_WwFK_P2C_fbQzWt7Phtxcq7Vzx2sGOcjne5k,8687
16
+ aegra_api/core/auth_middleware.py,sha256=1w72AuiypmCOmI4j5EgMJIzuI8nRyd40gT6Wp40trSE,11811
17
+ aegra_api/core/database.py,sha256=-vIg-m5xeAgGRXLIO94Il2snshyiFwpUsJGYY2YQ3d4,4599
18
+ aegra_api/core/health.py,sha256=bqfsFFuVia2WPTF2TxO8y8vNcoqaW1Qm9z-Q_c39xBU,4215
19
+ aegra_api/core/orm.py,sha256=yaS48OzWClD9dxbOItrEZuIJjo49BkW5puM9pJq6K54,7189
20
+ aegra_api/core/route_merger.py,sha256=cp_EBPmQujHkYq_G4V9DWsbDO8R0EIy-w7F6-mjuYaA,2396
21
+ aegra_api/core/sse.py,sha256=22S5v_Afo4BXZcVTrIe7UTUk5EDQYlhVZhLqZoiUEhM,6539
22
+ aegra_api/core/serializers/__init__.py,sha256=h1HrAcZoPNc8LC6lQS_c3mq1mCUdMS8TuSsERdQUDTg,320
23
+ aegra_api/core/serializers/base.py,sha256=DU3D8Y8YBBg-wBYngfKNQcWRexDbviLKTSg6DUARtGI,601
24
+ aegra_api/core/serializers/general.py,sha256=6z7UVLub4Or4jTlMiCD2QvvXTtVgxx2AdG6aV6ScaGE,2153
25
+ aegra_api/core/serializers/langgraph.py,sha256=rn6TVbd0_uiPIdBzp2RgQPq8JaXctaP-ZQx_yNduTnE,3960
26
+ aegra_api/middleware/__init__.py,sha256=Al0DGup5VcvUpnyy5R15bjjCuWbITcvuqFBWvavTF0w,218
27
+ aegra_api/middleware/double_encoded_json.py,sha256=c1HWcETWSXKAVdikxMEbvbQSjoSH0dLeMQVSY0L_jtM,2871
28
+ aegra_api/middleware/logger_middleware.py,sha256=KmiE2MPeKsed_TBhR5eGrQB6y3p9tryF_tuKp1P2ZZg,3904
29
+ aegra_api/models/__init__.py,sha256=1veRmyR-lHa8XMbUPdmjToyuXmR5ho9X5__Y7SUT2w4,1684
30
+ aegra_api/models/assistants.py,sha256=caPK028uVwcJXRQrg_wr_1qdcexSBgtOHdumCDVgImI,3547
31
+ aegra_api/models/auth.py,sha256=Ce7zdYqLe_TPsSLklPuoAr43ifhjkTAIHrtEvZCo1Ng,1659
32
+ aegra_api/models/enums.py,sha256=ukmJ1eaxmS8BtCQJ6TIfed2ZEypc_4M2ws9u9ivCBfE,434
33
+ aegra_api/models/errors.py,sha256=GhzORUu90i3iBwXLrirsXeLs4vbrSKd-Hh6X6sYG180,855
34
+ aegra_api/models/runs.py,sha256=7-ZJ5jdiY2g5HIc6cUHUYEBCyA2zBfLP3tso-cPo55Q,4444
35
+ aegra_api/models/store.py,sha256=jWNS02Hj-vTf6dhlrbTy-BVyKJHvBeCnEtN4Bdia4Jw,1936
36
+ aegra_api/models/threads.py,sha256=EUqSWUuVD9aahk-g9fw8auFY7KrTgN8HRC2mzAu6kVU,5852
37
+ aegra_api/observability/__init__.py,sha256=Ztbfd9zNj8IwSSl3K02DdavIdSXeeS9wTOwsrDolW0o,49
38
+ aegra_api/observability/base.py,sha256=Xthdf9yqSwRFPjpuJRjc8AU5TD222_CuVxDOCYkpN68,3068
39
+ aegra_api/observability/otel.py,sha256=7XjtzivwZtkACY_HM409qX7GpMq-oyDcY7u6S1PT5kE,4485
40
+ aegra_api/observability/setup.py,sha256=yw0-xdH2y1ihCleVz8fYtwQtLVwzeaJxZgm0oqliB9I,886
41
+ aegra_api/observability/targets/__init__.py,sha256=2csgqVutYZhLWyiqJS1LpplS-ViyIjD62z_MSo4K-uw,370
42
+ aegra_api/observability/targets/base.py,sha256=kzvvU5IvuukXnJRAY9qiNeUSprCf_oaj1JGVtlAxzfA,469
43
+ aegra_api/observability/targets/langfuse.py,sha256=RBcVec9WjI9-dnm079qcZfoboXpqd9bNvnPlECw5Cb4,1010
44
+ aegra_api/observability/targets/otlp.py,sha256=U3tPoFJOy_I73DPe-ZuzcxnFOUk0rtVp4KFIPWuyRdo,1222
45
+ aegra_api/observability/targets/phoenix.py,sha256=l5y4qK13DZm3OLX0XEGqf-X2_DUkCXDDv0c3Iq5I4cQ,736
46
+ aegra_api/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
+ aegra_api/services/assistant_service.py,sha256=d1h3r0l3q8HEiux9Hjf_Pj8xWu5WqpMe6PajHuMBX28,21810
48
+ aegra_api/services/base_broker.py,sha256=Tt7ddwxG0kAqgi5Su3ooWXjwCRQ5Sb4-v9Q6S8njf90,1700
49
+ aegra_api/services/broker.py,sha256=yxCE1Nt6ZhA4qBUubqN1_xG9zqb-AY3eZZf8STvuUzs,5226
50
+ aegra_api/services/event_converter.py,sha256=Mo6nmJDQVGEm2n4_mnAOkXGR3Y8LPZzetZaWQq1cDSA,6810
51
+ aegra_api/services/event_store.py,sha256=bQBSsFwhHm717Tus4BpLZkjAW9KXZuR2fa_5iUK8JCY,6878
52
+ aegra_api/services/graph_streaming.py,sha256=nmtOVkPP5HE1qV9PNREY_9YPRngyLyxoWKyeQz4hMoc,16392
53
+ aegra_api/services/langgraph_service.py,sha256=UXTVdgFeGmkBXerJel86MQhd4IVueHEP_c8ShHpDcC0,17812
54
+ aegra_api/services/streaming_service.py,sha256=YPxYqU_-PI84j_4qqz4JcDA9Ee2zNRofRbHLhVtdrnw,13708
55
+ aegra_api/services/thread_state_service.py,sha256=cDfCrkRKonZUhu3ihVjKtSiPepSLNVuOIj02zIUpgy0,5340
56
+ aegra_api/utils/__init__.py,sha256=6NGAF-Drv51Ai6jp0SrlpodO5dCO9PuqAxha3sCMbDY,139
57
+ aegra_api/utils/assistants.py,sha256=gQOQ4B7-Coy4FGekutEj-PxMS2leKjLUa1m66PB-1SM,852
58
+ aegra_api/utils/run_utils.py,sha256=8sx0I3loB7OnJ4e8gXBL21Ykcz4i14yYxWrEJ0H_gHE,2143
59
+ aegra_api/utils/setup_logging.py,sha256=JWx9GYadV30E6xhsMNHzr3OxMSQx-5pm0SuGDreLyCY,4723
60
+ aegra_api/utils/sse_utils.py,sha256=gGUZr5lnK2j9XqKevs0Q2-cN5ks76Us3a8unS0RVw1Y,684
61
+ aegra_api/utils/status_compat.py,sha256=eO-kuug3nr6E2JuARYhFVc3pQm1pNaOPCNVLi-UTmiI,1543
62
+ aegra_api-0.1.0.dist-info/METADATA,sha256=cOPn4v2YuXe2xvU7xJIy49KGd43YtrTzD4AP3jKNvaA,7293
63
+ aegra_api-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
64
+ aegra_api-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any