File size: 3,877 Bytes
be9fd4a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
"""Backend scale readiness (Redis, job queue) — not AI feature phases.

AI phases are defined in ``app.optimization.ai_phases`` (see docs/AI_FEATURES_PHASES.md).
"""

from __future__ import annotations

from typing import Any

from app.agentic.speculative_executor import speculative_execution_active
from app.config import settings
from app.db.database import multi_section_parallel_enabled, parallel_section_writes_safe
from app.llm.prompt_cache import prompt_caching_active
from app.redis_client import job_queue_enabled, redis_configured
def phase2_status() -> dict[str, Any]:
    """Async LLM, inspector speculation, and OpenAI prompt-cache helpers."""
    async_on = bool(settings.enable_async_pipeline)
    return {
        "enabled": async_on,
        "speculative_executor_active": speculative_execution_active(),
        "prompt_caching_active": prompt_caching_active(),
        "parallel_multi_section": multi_section_parallel_enabled(),
        "parallel_section_writes_safe": parallel_section_writes_safe(),
        "max_concurrent_llm_calls": int(settings.max_concurrent_llm_calls),
        "flags": {
            "enable_async_pipeline": async_on,
            "enable_speculative_executor": bool(settings.enable_speculative_executor),
            "enable_prompt_caching": bool(settings.enable_prompt_caching),
            "allow_sqlite_parallel_sections": bool(settings.allow_sqlite_parallel_sections),
        },
    }


def phase3_status() -> dict[str, Any]:
    """Redis-backed rate limits and optional generation job queue."""
    redis_on = redis_configured()
    queue_on = job_queue_enabled()
    return {
        "redis_configured": redis_on,
        "job_queue_active": queue_on,
        "job_queue_key": settings.job_queue_key if queue_on else None,
        "job_queue_max_concurrent": int(settings.job_queue_max_concurrent),
        "flags": {
            "redis_url_set": redis_on,
            "enable_job_queue": bool(settings.enable_job_queue),
        },
    }


def scale_optimization_active() -> bool:
    return bool(getattr(settings, "scale_optimization_profile", False))


def collect_scale_feature_warnings() -> list[str]:
    """Warnings when scale profile is on but sub-features cannot run."""
    warnings: list[str] = []
    if not scale_optimization_active():
        return warnings
    if settings.enable_async_pipeline and (settings.vectorstore_backend or "").lower() != "qdrant":
        if settings.enable_hybrid_retrieval or settings.semantic_cache_enabled:
            warnings.append(
                "SCALE_OPTIMIZATION_PROFILE: hybrid retrieval / semantic cache need "
                "VECTORSTORE_BACKEND=qdrant; async LLM, speculation, and prompt cache work with FAISS."
            )
    if settings.enable_speculative_executor and not speculative_execution_active():
        warnings.append(
            "ENABLE_SPECULATIVE_EXECUTOR=true but speculation is inactive "
            "(requires ENABLE_ASYNC_PIPELINE=true)."
        )
    if settings.enable_job_queue and not job_queue_enabled():
        warnings.append(
            "ENABLE_JOB_QUEUE=true requires REDIS_URL; jobs run in-process until Redis is set."
        )
    if job_queue_enabled() and not redis_configured():
        warnings.append("Job queue enabled without REDIS_URL (misconfiguration).")
    if (
        settings.enable_async_pipeline
        and multi_section_parallel_enabled()
        and not parallel_section_writes_safe()
    ):
        warnings.append(
            "Parallel multi-section generation is enabled but SQLite parallel writes "
            "are unsafe; set ALLOW_SQLITE_PARALLEL_SECTIONS=true or use PostgreSQL."
        )
    if settings.enable_prompt_caching and not prompt_caching_active():
        warnings.append(
            "ENABLE_PROMPT_CACHING=true requires ENABLE_ASYNC_PIPELINE=true."
        )
    return warnings