|
1 | 1 | # Architecture |
2 | 2 |
|
3 | | -```text |
4 | | -Caller |
5 | | - -> FastAPI boundary (:8080) |
6 | | - -> PromptEnvelope validation (cas-contracts v0.1) |
7 | | - -> WorkflowOrchestrator |
8 | | - -> LocalWorkflowAgentService (default) |
9 | | - -> FoundryWorkflowAgentService (configured) |
10 | | - -> AIProjectClient project Responses client |
11 | | - -> Next Gen agent_reference |
12 | | - -> canonical RunEvent records |
13 | | - -> OpenTelemetry spans |
14 | | - -> Application Insights when deployment injects configuration |
15 | | -``` |
| 3 | +The CAS Reference Product implements a robust boundary for the Coding Autopilot System, designed for deployment within an Azure Container Apps environment. The application uses a strictly typed schema for interactions, adopting canonical `cas-contracts` data structures. |
| 4 | + |
| 5 | +## System Architecture |
16 | 6 |
|
17 | | -The application owns workflow orchestration and lifecycle records. Foundry owns agent execution. `cas-platform` owns Container Apps, system-assigned identity, diagnostic settings, Log Analytics, and Application Insights resources. |
| 7 | +The following diagram visualizes the primary request flow and components within the application: |
18 | 8 |
|
19 | | -Foundry mode uses `ManagedIdentityCredential()` for every non-local environment. Local mode uses `DefaultAzureCredential()` only for developer convenience. No Classic Assistants API is used. |
| 9 | +```mermaid |
| 10 | +flowchart TD |
| 11 | + Client[Client] -->|POST /api/v1/workflows\nPromptEnvelope| FastAPI[FastAPI Server\napp.py] |
| 12 | + |
| 13 | + subgraph Core Application |
| 14 | + FastAPI --> Middleware[W3CTraceContextMiddleware\ntelemetry.py] |
| 15 | + Middleware --> Router[Workflow Router] |
| 16 | + Router --> Orchestrator[WorkflowOrchestrator\nworkflow.py] |
| 17 | + |
| 18 | + Orchestrator -->|Start Event| EventGen[RunEvent Generator\nmodels.py] |
| 19 | + Orchestrator --> AgentService{WorkflowAgentService\nworkflow.py} |
| 20 | + |
| 21 | + AgentService -->|Local Config| LocalAgent[LocalWorkflowAgentService] |
| 22 | + AgentService -->|Foundry Config| FoundryAgent[FoundryWorkflowAgentService] |
| 23 | + end |
| 24 | + |
| 25 | + subgraph External Infrastructure |
| 26 | + FoundryAgent -->|Managed Identity| AzureAuth[Azure DefaultAzureCredential\nidentity.py] |
| 27 | + AzureAuth -->|Responses API| AzureAI[Azure AI Projects API] |
| 28 | + AzureAI -->|Invoke Agent| FoundryNextGen[Foundry Next Gen Agent] |
| 29 | + end |
| 30 | + |
| 31 | + LocalAgent -->|Deterministic Output| Orchestrator |
| 32 | + FoundryAgent -->|Agent Output| Orchestrator |
| 33 | + |
| 34 | + Orchestrator -->|Complete Event| EventGen |
| 35 | + EventGen -->|WorkflowResult\nRunEvent| Router |
| 36 | + Router -->|200 OK| Client |
| 37 | + |
| 38 | + style FastAPI fill:#0a5c43,stroke:#fff,color:#fff |
| 39 | + style Orchestrator fill:#2d3748,stroke:#fff,color:#fff |
| 40 | + style AgentService fill:#b3531b,stroke:#fff,color:#fff |
| 41 | + style FoundryNextGen fill:#0d6efd,stroke:#fff,color:#fff |
| 42 | +``` |
20 | 43 |
|
21 | | -The Foundry call is isolated behind the `WorkflowAgentService` protocol. This keeps core lifecycle behavior deterministic and testable while making the external service boundary explicit. |
| 44 | +## Component Breakdown |
22 | 45 |
|
23 | | -## Deployment Interface |
| 46 | +1. **FastAPI Web Layer (`app.py`)**: |
| 47 | + - Exposes `/api/v1/workflows` for execution. |
| 48 | + - Provides `/health/live` and `/health/ready` for Kubernetes/Container Apps probes. |
| 49 | + - Manages OpenTelemetry spans, tracking request context via `PromptEnvelope.correlationId`. |
24 | 50 |
|
25 | | -`deployment/cas-platform.interface.yaml` records the application contract: Linux AMD64 image, port |
26 | | -8080, internal ingress by default, system-assigned identity, probes, and configuration inputs. It does |
27 | | -not deploy resources. |
| 51 | +2. **Telemetry (`telemetry.py`)**: |
| 52 | + - `W3CTraceContextMiddleware` ensures trace headers (`traceparent`, `tracestate`) are parsed and propagated properly across distributed systems. |
28 | 53 |
|
29 | | -The application consumes only the environment values listed in that interface. Platform resource IDs |
30 | | -and principal IDs remain deployment-orchestration outputs and are not application configuration. |
| 54 | +3. **Workflow Orchestrator (`workflow.py`)**: |
| 55 | + - Wraps the execution of the agent. |
| 56 | + - Emits canonical `RunEvent` data points (e.g., `workflow.started`, `workflow.completed`, `workflow.failed`). |
| 57 | + - Packages the final execution into a `WorkflowResult`. |
31 | 58 |
|
32 | | -## Observability Boundaries |
| 59 | +4. **Workflow Agent Service (`workflow.py`)**: |
| 60 | + - The application boundary for AI logic. |
| 61 | + - **Local Mode**: Bypasses the cloud entirely. Returns a deterministic output confirming the intake of constraints and intents. Useful for integration testing. |
| 62 | + - **Foundry Mode**: Uses `AIProjectClient` to invoke a designated Foundry Next Gen agent using the Responses API. |
33 | 63 |
|
34 | | -- Incoming HTTP requests are instrumented by Azure Monitor OpenTelemetry when configured. |
35 | | -- `cas.workflow.execute` covers core orchestration. |
36 | | -- `foundry.responses.create` covers the external Foundry call. |
37 | | -- CAS correlation IDs are attached to workflow spans and canonical events preserve W3C trace context. |
38 | | -- Broad Azure SDK and outbound HTTP auto-instrumentation is disabled to avoid capturing prompt or |
39 | | - output content. The application records only explicit boundary spans and safe identifiers. |
40 | | -# Loop execution boundaries |
| 64 | +5. **Data Models (`models.py`)**: |
| 65 | + - Strongly typed Pydantic models. |
| 66 | + - Requires explicit non-null values, enforcing high-quality data across boundaries (e.g., `PromptEnvelope`, `RunEvent`, `Actor`, `TraceContext`). |
41 | 67 |
|
42 | | -The public HTTP ingress is an Azure Functions Flex Consumption Linux app. It validates the canonical prompt envelope and returns `202` only after handing the message to Azure Queue Storage. It never invokes Foundry, executes tools, or runs sandbox work in the request process. A separately scaled worker owns those long-running operations. |
| 68 | +6. **Identity (`identity.py`)**: |
| 69 | + - Uses `DefaultAzureCredential` for local development or system-assigned `ManagedIdentityCredential` in Azure. |
| 70 | + - Follows security best practices by strictly avoiding hardcoded secrets or API keys. |
43 | 71 |
|
44 | | -The ingress uses a system-assigned managed identity. Bicep grants Storage Queue Data Contributor on the workload storage account and Azure AI User on the specific Foundry project. No account keys, API keys, or connection-string credentials are materialized. Local development continues to use `DefaultAzureCredential`; Azure environments use `ManagedIdentityCredential`. |
| 72 | +## Deployment Strategy |
45 | 73 |
|
46 | | -Loop spans use W3C trace context and the fixed stages `control_plane`, `worker`, `tool`, `verifier`, and `foundry`. Attributes are limited to correlation, goal, and work-item identifiers; prompts and model output are not telemetry attributes. |
| 74 | +The application is meant to be packaged as a Docker container, running rootless. It's built for the **cas-platform** ecosystem, which dictates the Azure resources, network topology, and Managed Identity mappings externally. |
0 commit comments