Dataface Tasks

Refactor Cloud AI chat stream into scoped execution services

IDMCP_ANALYST_AGENT-REFACTOR_CLOUD_AI_CHAT_STREAM_INTO_SCOPED_EXECUTION_SERVICES
Statuscompleted
Priorityp1
Milestonem1-ft-analytics-analyst-pilot
Ownerdata-ai-engineer-architect

Problem

Refactor apps/cloud/apps/ai/views.py chat_stream into smaller scope-resolution, tool-execution, and SSE-streaming units. Introduce an explicit execution context object so auth, project selection, context assembly, and async bridging are no longer coupled inside one controller function.

Context

chat_stream in apps/cloud/apps/ai/views.py (lines 118–241) is a single 120-line view that mixes: - Auth/membership check - JSON request parsing - AI service availability check - Scope resolution (project vs org) with different context assembly - Tool executor closure construction - Async-to-sync SSE bridging with event-loop management

Existing tests in tests/cloud/test_chat_stream.py are source-code inspection tests that read views.py and assert specific strings. Any refactor must keep extracted code in views.py to avoid breaking those tests.

Key files: apps/cloud/apps/ai/views.py, apps/cloud/apps/ai/service.py, apps/cloud/apps/ai/urls.py, apps/cloud/apps/ai/org_urls.py.

Possible Solutions

  1. Extract to separate service module — Move scope resolution and SSE generation to a new chat_service.py. Trade-off: breaks 10+ existing source-code-inspection tests that read views.py.

  2. Recommended: Extract helpers within views.py — Create a ChatExecutionContext dataclass, a resolve_chat_scope() function, and a generate_chat_sse() generator in the same file. chat_stream becomes a thin controller composing these. Preserves all existing tests since strings stay in views.py. Minimal abstraction, no new files.

  3. Class-based view — Convert to a CBV with methods per concern. Trade-off: over-engineered for one endpoint, breaks existing test assertions on def chat_stream(.

Plan

Approach #2. Files to modify: apps/cloud/apps/ai/views.py. New test file: tests/cloud/test_chat_stream_refactor.py.

Steps: 1. Write failing tests for new structure (ChatExecutionContext, resolve_chat_scope, generate_chat_sse) 2. Add ChatExecutionContext dataclass 3. Extract resolve_chat_scope() — scope validation, project lookup, context assembly 4. Extract generate_chat_sse() — async bridge, event loop, SSE formatting 5. Slim chat_stream to compose these three pieces 6. Run existing + new tests to confirm all pass

Implementation Progress

Key decisions

  • Kept all extracted code in views.py to preserve 49 existing source-code-inspection tests.
  • Used a plain @dataclass (ChatExecutionContext) — no Pydantic, no base class. Just fields.
  • resolve_chat_scope returns ChatExecutionContext | JsonResponse — union return avoids exception-based control flow.
  • generate_chat_sse is a standalone generator that owns the event loop lifecycle.

Changes

  • apps/cloud/apps/ai/views.py: Added ChatExecutionContext dataclass, resolve_chat_scope(), generate_chat_sse(). Slimmed chat_stream from ~120 lines to ~30 lines.
  • tests/cloud/test_chat_stream_refactor.py (new): 17 tests verifying the new structure exists and chat_stream composes the helpers.

Validation

  • 66/66 tests pass across test_chat_stream.py + test_chat_stream_refactor.py
  • 215/215 tests pass across all tests/cloud/ + tests/ai/
  • ruff check and black --check clean

QA Exploration

  • [x] QA exploration completed (or N/A for non-UI tasks)

N/A — backend-only refactor, no UI changes.

Review Feedback

  • Manager review (just review) approved with follow-up fixes.
  • Restored org_slug in exception logging so production failures keep their original diagnostic context.
  • Removed asyncio.set_event_loop(loop) from generate_chat_sse() to avoid mutating thread-local event loop state in request threads.
  • Manager validation after review fixes:
  • uv run pytest tests/cloud/test_chat_stream.py tests/cloud/test_chat_stream_refactor.py tests/ai -q
  • uv run ruff check apps/cloud/apps/ai/views.py tests/cloud/test_chat_stream_refactor.py
  • uv run black --check apps/cloud/apps/ai/views.py tests/cloud/test_chat_stream_refactor.py
  • [ ] Review cleared