alms-cli 0.1.7__tar.gz → 0.1.9__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.
- {alms_cli-0.1.7 → alms_cli-0.1.9}/PKG-INFO +1 -1
- {alms_cli-0.1.7 → alms_cli-0.1.9}/pyproject.toml +1 -1
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/__init__.py +1 -1
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/.env.example.j2 +2 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/pyproject.toml.j2 +3 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/endpoints/v1/dependencies.py.j2 +5 -2
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/endpoints/v1/health.py.j2 +5 -1
- alms_cli-0.1.9/src/alms_cli/templates/files/src/api/endpoints/v1/sample_agent.py.j2 +15 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/main.py.j2 +21 -19
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/config/settings.py.j2 +6 -5
- alms_cli-0.1.9/src/alms_cli/templates/files/src/providers/ai/factory.py.j2 +9 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/providers/ai/langchain_model_loader.py.j2 +3 -3
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/tests/integration/test_full_stack.py.j2 +2 -1
- alms_cli-0.1.9/src/alms_cli/templates/files/src/tests/v1/test_agent.py.j2 +18 -0
- alms_cli-0.1.9/src/alms_cli/templates/files/src/tests/v1/test_health.py.j2 +19 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/tests/v1/test_observability_middleware.py.j2 +2 -1
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/ui/components.py +28 -8
- alms_cli-0.1.7/src/alms_cli/templates/files/src/api/endpoints/v1/sample_agent.py.j2 +0 -15
- alms_cli-0.1.7/src/alms_cli/templates/files/src/providers/ai/factory.py.j2 +0 -10
- alms_cli-0.1.7/src/alms_cli/templates/files/src/tests/v1/test_agent.py.j2 +0 -10
- alms_cli-0.1.7/src/alms_cli/templates/files/src/tests/v1/test_health.py.j2 +0 -12
- {alms_cli-0.1.7 → alms_cli-0.1.9}/.gitignore +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/LICENSE +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/README.md +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/__main__.py +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/commands/__init__.py +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/commands/info.py +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/commands/init.py +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/main.py +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/__init__.py +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/.github/ISSUE_TEMPLATE/bug_report.yml.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/.github/ISSUE_TEMPLATE/feature_request.yml.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/.github/dependabot.yml.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/.github/pull_request_template.md.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/.github/workflows/ci.yml.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/.gitignore.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/Dockerfile.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/README.md.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/alembic/README.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/alembic/env.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/alembic/script.py.mako.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/alembic.ini.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/docker-compose.yml.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/docs/01-System-Design.md.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/docs/02-Design-Patterns.md.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/docs/03-Database-Design.md.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/docs/04-Tech-Stack.md.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/docs/05-Project-Structure.md.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/docs/06-API-Documentation.md.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/docs/07-Setup-Installation.md.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/docs/08-Contribution-Guide.md.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/pytest.ini.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/rules/project_rules.md.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/agents/agent_manager/agent.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/agents/prompts/sample_agent_prompt.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/endpoints/v1/metrics.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/endpoints/v1/routers.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/endpoints/v1/sample_di.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/endpoints/v1/schemas/base.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/endpoints/v1/schemas/sample.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/middlewares/error_handler.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/middlewares/logging.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/middlewares/observability.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/middlewares/security.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/router/routers.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/config/logs_config.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/core/exceptions.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/database/connection.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/database/repositories/base.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/database/repositories/sqlalchemy_repository.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/execution/actions/sample_action.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/execution/usecases/sample_usecase.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/observability/__init__.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/observability/metrics.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/observability/tracing.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/providers/ai/base.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/tests/README.md.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/tests/conftest.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/tests/e2e/test_workflows.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/tests/v1/test_metrics.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/tests/v1/test_metrics_endpoint.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/tests/v1/test_sqlalchemy_repository.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/tests/v1/test_tracing.py.j2 +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/generator.py +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/profiles.py +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/template_renderer.py +0 -0
- {alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/ui/__init__.py +0 -0
|
@@ -7,6 +7,8 @@ SERVICE_NAME={{ project_name | lower | replace(' ', '-') }}
|
|
|
7
7
|
# Server Configuration
|
|
8
8
|
SERVER_PORT=3000
|
|
9
9
|
SERVER_HOST=0.0.0.0
|
|
10
|
+
# WARNING: ALLOWED_HOSTS=["*"] is for development only.
|
|
11
|
+
# Production must use explicit origins, e.g. ALLOWED_HOSTS=["https://example.com"]
|
|
10
12
|
ALLOWED_HOSTS=["*"]
|
|
11
13
|
|
|
12
14
|
# Environment Configuration
|
|
@@ -18,8 +18,11 @@ def get_db_session():
|
|
|
18
18
|
return get_db()
|
|
19
19
|
{% else %}
|
|
20
20
|
def get_db_session():
|
|
21
|
-
"""Get database session."""
|
|
22
|
-
|
|
21
|
+
"""Get database session (stub for non-database profiles)."""
|
|
22
|
+
raise RuntimeError(
|
|
23
|
+
"Database is not enabled in this profile. "
|
|
24
|
+
"Regenerate with --profile db-agent or full to enable database support."
|
|
25
|
+
)
|
|
23
26
|
{% endif %}{% if has_ai %}
|
|
24
27
|
|
|
25
28
|
try:
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/endpoints/v1/health.py.j2
RENAMED
|
@@ -29,7 +29,11 @@ async def ready_check():
|
|
|
29
29
|
try:
|
|
30
30
|
from src.database.connection import check_database_connection
|
|
31
31
|
except ImportError:
|
|
32
|
-
|
|
32
|
+
from fastapi.responses import JSONResponse
|
|
33
|
+
return JSONResponse(
|
|
34
|
+
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
|
35
|
+
content=AppResponse(success=False, data={"status": "degraded", "ready": False}).model_dump(),
|
|
36
|
+
)
|
|
33
37
|
db_ready = await check_database_connection()
|
|
34
38
|
if db_ready:
|
|
35
39
|
return AppResponse(success=True, data={"status": "ready", "ready": True, "dependencies": {"database": "healthy"}})
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Sample agent endpoint."""
|
|
2
|
+
|
|
3
|
+
from fastapi import APIRouter, Depends
|
|
4
|
+
from src.api.endpoints.v1.dependencies import get_sample_usecase
|
|
5
|
+
from src.api.endpoints.v1.schemas.base import AppResponse
|
|
6
|
+
from src.api.endpoints.v1.schemas.sample import SampleRequest
|
|
7
|
+
|
|
8
|
+
router = APIRouter()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@router.post("/sample")
|
|
12
|
+
async def sample_agent(request: SampleRequest, usecase=Depends(get_sample_usecase)):
|
|
13
|
+
"""Sample agent endpoint."""
|
|
14
|
+
result = await usecase.execute(query=request.query)
|
|
15
|
+
return AppResponse(success=True, data=result)
|
|
@@ -38,22 +38,34 @@ def create_app() -> FastAPI:
|
|
|
38
38
|
redoc_url=None,
|
|
39
39
|
)
|
|
40
40
|
|
|
41
|
-
# Middleware registration order matters
|
|
42
|
-
#
|
|
43
|
-
app.add_middleware(LoggingMiddleware)
|
|
44
|
-
{% if has_obs %} app.add_middleware(ObservabilityMiddleware)
|
|
45
|
-
{% endif %} app.add_middleware(SecurityHeadersMiddleware)
|
|
46
|
-
app.add_middleware(APIKeyMiddleware)
|
|
47
|
-
app.add_middleware(ErrorHandlerMiddleware)
|
|
41
|
+
# Middleware registration order matters: last added = outermost = executes first on incoming request.
|
|
42
|
+
# Intended request flow: Logging → APIKey → ErrorHandler → SecurityHeaders → Observability → CORS
|
|
48
43
|
app.add_middleware(
|
|
49
44
|
CORSMiddleware,
|
|
50
|
-
allow_origins=
|
|
45
|
+
allow_origins=settings.ALLOWED_HOSTS,
|
|
51
46
|
allow_credentials=True,
|
|
52
47
|
allow_methods=["*"],
|
|
53
48
|
allow_headers=["*"],
|
|
54
49
|
)
|
|
50
|
+
app.add_middleware(ErrorHandlerMiddleware)
|
|
51
|
+
app.add_middleware(APIKeyMiddleware)
|
|
52
|
+
app.add_middleware(SecurityHeadersMiddleware)
|
|
53
|
+
{% if has_obs %} app.add_middleware(ObservabilityMiddleware)
|
|
54
|
+
{% endif %} app.add_middleware(LoggingMiddleware)
|
|
55
55
|
|
|
56
56
|
app.include_router(api_router, prefix=settings.API_PREFIX)
|
|
57
|
+
{% if has_scalar %}
|
|
58
|
+
|
|
59
|
+
# Scalar API Documentation
|
|
60
|
+
try:
|
|
61
|
+
from scalar_fastapi import get_scalar_api_reference
|
|
62
|
+
|
|
63
|
+
@app.get("/docs", include_in_schema=False)
|
|
64
|
+
async def scalar_html():
|
|
65
|
+
return get_scalar_api_reference(openapi_url=app.openapi_url, title=app.title)
|
|
66
|
+
except ImportError:
|
|
67
|
+
pass
|
|
68
|
+
{% endif %}
|
|
57
69
|
return app
|
|
58
70
|
|
|
59
71
|
|
|
@@ -66,14 +78,4 @@ if __name__ == "__main__":
|
|
|
66
78
|
host=settings.SERVER_HOST,
|
|
67
79
|
port=settings.SERVER_PORT,
|
|
68
80
|
reload=settings.DEBUG,
|
|
69
|
-
)
|
|
70
|
-
{% if has_scalar %}
|
|
71
|
-
|
|
72
|
-
try:
|
|
73
|
-
from scalar_fastapi import get_scalar_api_reference
|
|
74
|
-
@app.get("/docs", include_in_schema=False)
|
|
75
|
-
async def scalar_html():
|
|
76
|
-
return get_scalar_api_reference(openapi_url=app.openapi_url, title=app.title)
|
|
77
|
-
except ImportError:
|
|
78
|
-
pass
|
|
79
|
-
{% endif %}
|
|
81
|
+
)
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"""Application settings."""
|
|
2
2
|
|
|
3
|
-
from pydantic_settings import BaseSettings
|
|
4
3
|
from functools import lru_cache
|
|
5
4
|
|
|
5
|
+
from pydantic import ConfigDict
|
|
6
|
+
from pydantic_settings import BaseSettings
|
|
7
|
+
|
|
6
8
|
|
|
7
9
|
class Settings(BaseSettings):
|
|
8
10
|
APP_NAME: str = "ALMS Backend"
|
|
@@ -15,7 +17,8 @@ class Settings(BaseSettings):
|
|
|
15
17
|
{% if has_ai %} AI_ENABLED: bool = False
|
|
16
18
|
{% endif %}{% if has_db %} DATABASE_ENABLED: bool = True
|
|
17
19
|
{% endif %}{% if has_redis %} REDIS_ENABLED: bool = False
|
|
18
|
-
{% endif %}{% if has_ai %}
|
|
20
|
+
{% endif %}{% if has_ai %} MODEL_PROVIDER: str = "openai" # reserved for future provider selection; only "openai" is supported
|
|
21
|
+
OPENAI_API_KEY: str = ""
|
|
19
22
|
OPENAI_MODEL_BASIC: str = "gpt-4o-mini"
|
|
20
23
|
OPENAI_MODEL_REASONING: str = "gpt-4o"
|
|
21
24
|
{% endif %}{% if has_db %} DATABASE_URL: str | None = None
|
|
@@ -43,9 +46,7 @@ class Settings(BaseSettings):
|
|
|
43
46
|
if "*" in self.ALLOWED_HOSTS:
|
|
44
47
|
raise ValueError("ALLOWED_HOSTS must not contain * in production")
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
env_file = ".env"
|
|
48
|
-
case_sensitive = True
|
|
49
|
+
model_config = ConfigDict(env_file=".env", case_sensitive=True)
|
|
49
50
|
|
|
50
51
|
|
|
51
52
|
@lru_cache()
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""AI provider factory."""
|
|
2
|
+
|
|
3
|
+
from src.providers.ai.base import AIModelProvider
|
|
4
|
+
from src.providers.ai.langchain_model_loader import LangchainModelLoader
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def get_ai_provider() -> AIModelProvider:
|
|
8
|
+
"""Return the configured AI provider."""
|
|
9
|
+
return LangchainModelLoader()
|
|
@@ -5,8 +5,8 @@ from src.config.settings import settings
|
|
|
5
5
|
from src.providers.ai.base import AIModelProvider
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
class
|
|
9
|
-
"""LangChain AI model
|
|
8
|
+
class LangchainModelLoader(AIModelProvider):
|
|
9
|
+
"""LangChain AI model loader."""
|
|
10
10
|
|
|
11
11
|
def get_chat_model(self, tier: str = "basic"):
|
|
12
12
|
"""Get LLM instance."""
|
|
@@ -24,4 +24,4 @@ class LangChainModelProvider(AIModelProvider):
|
|
|
24
24
|
|
|
25
25
|
def get_llm(model: str = "basic"):
|
|
26
26
|
"""Get LLM instance."""
|
|
27
|
-
return
|
|
27
|
+
return LangchainModelLoader().get_chat_model(tier=model)
|
|
@@ -7,4 +7,5 @@ import pytest
|
|
|
7
7
|
async def test_full_stack(client):
|
|
8
8
|
"""Test full stack integration."""
|
|
9
9
|
response = await client.get("/api/v1/health")
|
|
10
|
-
|
|
10
|
+
# Health returns 200 when all deps healthy, 503 when degraded (e.g., no DB)
|
|
11
|
+
assert response.status_code in (200, 503)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Agent endpoint tests."""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@pytest.mark.asyncio
|
|
7
|
+
async def test_sample_agent(client):
|
|
8
|
+
"""Test sample agent endpoint."""
|
|
9
|
+
response = await client.post("/api/v1/agent/sample", json={"query": "test"})
|
|
10
|
+
# Endpoint returns 200 when AI deps are available, 503 when not installed
|
|
11
|
+
assert response.status_code in (200, 503)
|
|
12
|
+
data = response.json()
|
|
13
|
+
assert "success" in data
|
|
14
|
+
if response.status_code == 200:
|
|
15
|
+
assert data["success"] is True
|
|
16
|
+
else:
|
|
17
|
+
assert data["success"] is False
|
|
18
|
+
assert data["error"]["code"] == "AGENT_UNAVAILABLE"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Health endpoint tests."""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@pytest.mark.asyncio
|
|
7
|
+
async def test_health_check(client):
|
|
8
|
+
"""Test health check endpoint."""
|
|
9
|
+
response = await client.get("/api/v1/health")
|
|
10
|
+
# Health endpoint returns 200 when healthy, 503 when degraded (e.g., DB unavailable)
|
|
11
|
+
assert response.status_code in (200, 503)
|
|
12
|
+
data = response.json()
|
|
13
|
+
assert "success" in data
|
|
14
|
+
assert "data" in data
|
|
15
|
+
if response.status_code == 200:
|
|
16
|
+
assert data["success"] is True
|
|
17
|
+
else:
|
|
18
|
+
assert data["success"] is False
|
|
19
|
+
assert data["data"]["status"] == "degraded"
|
|
@@ -7,4 +7,5 @@ import pytest
|
|
|
7
7
|
async def test_observability_middleware(client):
|
|
8
8
|
"""Test observability middleware."""
|
|
9
9
|
response = await client.get("/api/v1/health")
|
|
10
|
-
|
|
10
|
+
# Health returns 200 when all deps healthy, 503 when degraded (e.g., no DB)
|
|
11
|
+
assert response.status_code in (200, 503)
|
|
@@ -1,18 +1,38 @@
|
|
|
1
1
|
"""Rich UI components for beautiful terminal output."""
|
|
2
2
|
|
|
3
|
+
import sys
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from rich import box
|
|
3
7
|
from rich.console import Console
|
|
4
8
|
from rich.panel import Panel
|
|
5
|
-
from rich.tree import Tree
|
|
6
9
|
from rich.progress import (
|
|
10
|
+
BarColumn,
|
|
7
11
|
Progress,
|
|
8
12
|
SpinnerColumn,
|
|
9
13
|
TextColumn,
|
|
10
|
-
BarColumn,
|
|
11
14
|
TimeElapsedColumn,
|
|
12
15
|
)
|
|
13
16
|
from rich.table import Table
|
|
14
|
-
from rich import
|
|
15
|
-
|
|
17
|
+
from rich.tree import Tree
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _stdout_supports_unicode() -> bool:
|
|
21
|
+
"""Check whether stdout can encode Unicode symbols (e.g. not cp1252)."""
|
|
22
|
+
encoding = getattr(sys.stdout, "encoding", None) or ""
|
|
23
|
+
try:
|
|
24
|
+
"\u2139".encode(encoding)
|
|
25
|
+
return True
|
|
26
|
+
except (UnicodeEncodeError, LookupError):
|
|
27
|
+
return False
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# ponytail: ASCII fallbacks for Windows cp1252 terminals where Unicode glyphs crash stdout.
|
|
31
|
+
_unicode_ok = _stdout_supports_unicode()
|
|
32
|
+
SYM_OK = "\u2713" if _unicode_ok else "[OK]"
|
|
33
|
+
SYM_ERR = "\u2717" if _unicode_ok else "[X]"
|
|
34
|
+
SYM_INFO = "\u2139" if _unicode_ok else "[i]"
|
|
35
|
+
SYM_WARN = "\u26a0" if _unicode_ok else "[!]"
|
|
16
36
|
|
|
17
37
|
console = Console()
|
|
18
38
|
|
|
@@ -42,22 +62,22 @@ def print_step(step_num: int, total: int, message: str):
|
|
|
42
62
|
|
|
43
63
|
def print_success(message: str):
|
|
44
64
|
"""Print a success message."""
|
|
45
|
-
console.print(f"[bold green]
|
|
65
|
+
console.print(f"[bold green]{SYM_OK}[/bold green] [green]{message}[/green]")
|
|
46
66
|
|
|
47
67
|
|
|
48
68
|
def print_error(message: str):
|
|
49
69
|
"""Print an error message."""
|
|
50
|
-
console.print(f"[bold red]
|
|
70
|
+
console.print(f"[bold red]{SYM_ERR}[/bold red] [red]{message}[/red]")
|
|
51
71
|
|
|
52
72
|
|
|
53
73
|
def print_info(message: str):
|
|
54
74
|
"""Print an info message."""
|
|
55
|
-
console.print(f"[bold blue]
|
|
75
|
+
console.print(f"[bold blue]{SYM_INFO}[/bold blue] [blue]{message}[/blue]")
|
|
56
76
|
|
|
57
77
|
|
|
58
78
|
def print_warning(message: str):
|
|
59
79
|
"""Print a warning message."""
|
|
60
|
-
console.print(f"[bold yellow]
|
|
80
|
+
console.print(f"[bold yellow]{SYM_WARN}[/bold yellow] [yellow]{message}[/yellow]")
|
|
61
81
|
|
|
62
82
|
|
|
63
83
|
def create_progress():
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"""Sample agent endpoint."""
|
|
2
|
-
|
|
3
|
-
from fastapi import APIRouter
|
|
4
|
-
from src.api.endpoints.v1.schemas.base import AppResponse
|
|
5
|
-
from src.execution.usecases.sample_usecase import SampleUseCase
|
|
6
|
-
|
|
7
|
-
router = APIRouter()
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@router.post("/sample")
|
|
11
|
-
async def sample_agent(query: str):
|
|
12
|
-
"""Sample agent endpoint."""
|
|
13
|
-
usecase = SampleUseCase()
|
|
14
|
-
result = await usecase.execute(query)
|
|
15
|
-
return AppResponse(success=True, data=result)
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"""AI provider factory."""
|
|
2
|
-
|
|
3
|
-
from functools import lru_cache
|
|
4
|
-
from src.providers.ai.langchain_model_loader import LangChainModelProvider
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
@lru_cache
|
|
8
|
-
def get_ai_provider() -> LangChainModelProvider:
|
|
9
|
-
"""Return the configured AI provider."""
|
|
10
|
-
return LangChainModelProvider()
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"""Agent endpoint tests."""
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
@pytest.mark.asyncio
|
|
7
|
-
async def test_sample_agent(client):
|
|
8
|
-
"""Test sample agent endpoint."""
|
|
9
|
-
response = await client.post("/api/v1/agent/sample", json={"query": "test"})
|
|
10
|
-
assert response.status_code == 200
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"""Health endpoint tests."""
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
@pytest.mark.asyncio
|
|
7
|
-
async def test_health_check(client):
|
|
8
|
-
"""Test health check endpoint."""
|
|
9
|
-
response = await client.get("/api/v1/health")
|
|
10
|
-
assert response.status_code == 200
|
|
11
|
-
data = response.json()
|
|
12
|
-
assert data["success"] is True
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/.github/pull_request_template.md.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/docs/02-Design-Patterns.md.j2
RENAMED
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/docs/03-Database-Design.md.j2
RENAMED
|
File without changes
|
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/docs/05-Project-Structure.md.j2
RENAMED
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/docs/06-API-Documentation.md.j2
RENAMED
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/docs/07-Setup-Installation.md.j2
RENAMED
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/docs/08-Contribution-Guide.md.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/agents/agent_manager/agent.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/endpoints/v1/metrics.py.j2
RENAMED
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/endpoints/v1/routers.py.j2
RENAMED
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/endpoints/v1/sample_di.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/middlewares/logging.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/api/middlewares/security.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/database/connection.py.j2
RENAMED
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/database/repositories/base.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/observability/__init__.py.j2
RENAMED
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/observability/metrics.py.j2
RENAMED
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/observability/tracing.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/tests/e2e/test_workflows.py.j2
RENAMED
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/tests/v1/test_metrics.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{alms_cli-0.1.7 → alms_cli-0.1.9}/src/alms_cli/templates/files/src/tests/v1/test_tracing.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|