refactor: decompose large monolithic modules into focused packages#27
refactor: decompose large monolithic modules into focused packages#27
Conversation
| """ | ||
| if body.stream: | ||
| return StreamingResponse( | ||
| _stream_chat_completion(body), |
Check warning
Code scanning / CodeQL
Information exposure through an exception Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 7 hours ago
In general, the fix is to avoid sending raw exception messages to the client. Instead, log the detailed error server-side and return a generic, sanitized message over SSE that does not leak internal details. This keeps observability for developers while protecting users from seeing stack traces or sensitive provider/backend messages.
Concretely, the best change with minimal behavioral impact is:
- Keep the existing
_format_sse_errorhelper and the SSE error shape. - Change
_stream_chat_completion’sexceptblock so it:- Logs the full exception (including stack trace) using
logging.exception. - Sends a generic error string (e.g.
"An internal error occurred during streaming.") to_format_sse_errorinstead ofstr(e).
- Logs the full exception (including stack trace) using
This only affects:
src/api/routes/openai_compat/handlers.py: update theexcept Exception as e:block at the end of_stream_chat_completionand add an import forlogging.
No changes are needed inroutes.pyorutils.pybeyond this, because_format_sse_errorwill no longer receive sensitive messages.
To implement:
- Add
import loggingalongside the existing imports inhandlers.py. - Change the
exceptblock:
except Exception as e:
import logging
logging.exception("Unhandled error in _stream_chat_completion")
yield _format_sse_error("An internal error occurred during streaming.")This preserves the SSE structure (data: { "error": { "message": ..., "type": "api_error" } }) and the client contract, but replaces the sensitive content with a safe, generic message.
| @@ -6,6 +6,7 @@ | ||
| import time | ||
| from typing import TYPE_CHECKING, Any | ||
| from uuid import uuid4 | ||
| import logging | ||
|
|
||
| from fastapi import HTTPException | ||
| from langchain_core.messages import AIMessage | ||
| @@ -446,4 +447,6 @@ | ||
| await session.commit() | ||
|
|
||
| except Exception as e: | ||
| yield _format_sse_error(str(e)) | ||
| # Log full exception server-side, but send a generic message to the client | ||
| logging.exception("Unhandled error in _stream_chat_completion") | ||
| yield _format_sse_error("An internal error occurred during streaming.") |
ffb1d02 to
fb556fe
Compare
fb556fe to
bb96107
Compare
Breaks down 8 oversized modules (architect.py, data_scientist.py, llm.py, mlflow.py, specialist_tools.py, openai_compat route, ha_registry route, agents route) into well-organized packages with clear single-responsibility modules. Extracts UI components into dedicated directories. Resolves all mypy type errors introduced by decomposition (92 -> 0). Key changes: - architect.py -> src/agents/architect/ (7 modules) - data_scientist.py -> src/agents/data_scientist/ (2 modules) - llm.py -> src/llm/ (factory, resilient, circuit_breaker, usage) - mlflow.py -> src/tracing/ (init, tracer, spans, runs, logging, feedback) - specialist_tools.py -> split into routing, runners, strategies, consult - openai_compat route -> package with handlers, streaming_filter, schemas - ha_registry route -> package with sub-routers - agents route -> package with sub-routers - Extract analyst mixins (config, discussion, persistence) - Extract graph state into package (base, conversation, analysis, etc.) - Decompose UI pages (diagnostics, architecture, dashboard, inline-assistant) - All facade modules preserved for backward-compatible imports Co-authored-by: Cursor <cursoragent@cursor.com>
bb96107 to
10a50b3
Compare
Summary
Motivation
Several core modules had grown beyond 800-1200 lines, making navigation, testing, and code review difficult. This refactor improves maintainability without changing any behavior.
Type of Change
refactor— Code restructuring (no feature or fix)Changes
Backend decomposition (8 modules -> packages):
src/agents/architect.py->src/agents/architect/(agent, workflow, proposals, review, tools, entity_context, stream_event)src/agents/data_scientist.py->src/agents/data_scientist/(agent, collectors, constants, prompts, suggestions, workflow)src/llm.py->src/llm/(factory, resilient, circuit_breaker, usage)src/tracing/mlflow.py->src/tracing/(init, tracer, spans, runs, logging, feedback)src/tools/specialist_tools.py-> split into routing, runners, strategies, consult modulessrc/api/routes/openai_compat.py-> package (handlers, streaming_filter, schemas, utils)src/api/routes/ha_registry.py-> package (automations, scenes, scripts, services, summary, sync, helpers)src/api/routes/agents.py-> package (core, config_versions, prompt_versions, schemas, seed, serializers)Additional extractions:
UI decomposition:
Backward compatibility:
__init__.pyfiles re-export public symbols)Type safety:
_safe_import_mlflow(eliminated 23 cascade errors)Testing
make ci-localpasses (ruff format, ruff check, mypy 0 errors/269 files, bandit, 2717 tests pass)Security Considerations
This is a pure structural refactor. No behavioral changes, no new endpoints, no auth/crypto changes.
Checklist
make ci-local)