Skip to content

[DEV] Implement AzureFoundryService as IAiService provider #119

Description

@artcava

Summary

Implement AzureFoundryService as a concrete provider of IAiService, integrated via the existing AiServiceFactory + AiProvider keyed DI architecture. This is a priority item: it must be ready before the Azure MeetUp Torino (see #118), where it will be presented as a real-world Azure AI Foundry integration within XPoster.


Context

AiServiceFactory already supports keyed DI resolution by AiProvider enum. OpenAiService is the only active implementation today. AzureFoundryService is the next provider to implement — it does not replace OpenAI but acts as an alternative provider selectable via configuration.

The AiProvider.AzureFoundry enum value is expected to already exist (or must be added) in src/Abstraction/AiProvider.cs.


Implementation Plan

1. src/Models/AzureFoundryOptions.cs

Strongly-typed configuration bound from the AzureFoundry configuration section:

public sealed class AzureFoundryOptions
{
    public string Endpoint { get; set; } = string.Empty;
    public string ApiKey { get; set; } = string.Empty;
    public string DeploymentName { get; set; } = string.Empty;
    public string ImageDeploymentName { get; set; } = string.Empty;
    public string ApiVersion { get; set; } = "2024-02-01";
    public double SummaryTemperature { get; set; } = 0.5;
    public int SummaryMaxTokensPerChar { get; set; } = 5;
    public int SummarySafetyMarginChars { get; set; } = 50;
    public string SummarySystemPromptTemplate { get; set; } = "...";
    public string SummaryUserPromptTemplate { get; set; } = "...";
    public string ImagePromptSystemTemplate { get; set; } = "...";
    public string ImagePromptUserTemplate { get; set; } = "...";
    public int ImagePromptMaxTokens { get; set; } = 60;
    public double ImagePromptTemperature { get; set; } = 0.7;
}

Add AzureFoundryOptionsValidator.cs — validate that Endpoint, ApiKey, and DeploymentName are not empty when AiProvider.AzureFoundry is active.


2. src/Services/AzureFoundryService.cs

Implement IAiService using the Azure AI Foundry REST API (OpenAI-compatible endpoint):

  • GetSummaryAsync — POST to {Endpoint}/openai/deployments/{DeploymentName}/chat/completions?api-version={ApiVersion}
  • GetImagePromptAsync — same endpoint, image prompt templates
  • GenerateImageAsync — POST to {Endpoint}/openai/deployments/{ImageDeploymentName}/images/generations?api-version={ApiVersion} (DALL-E compatible)

Use IHttpClientFactory. Set api-key header from AzureFoundryOptions.ApiKey.


3. Program.cs

builder.Services.AddKeyedTransient<IAiService, AzureFoundryService>(AiProvider.AzureFoundry);
builder.Services.Configure<AzureFoundryOptions>(builder.Configuration.GetSection("AzureFoundry"));
builder.Services.AddSingleton<IValidateOptions<AzureFoundryOptions>, AzureFoundryOptionsValidator>();

4. AiServiceFactory.cs

Add AiProvider.AzureFoundry to the supported providers set.


5. Configuration files

src/local.settings.json.example:

"AzureFoundry__Endpoint": "",
"AzureFoundry__ApiKey": "",
"AzureFoundry__DeploymentName": "",
"AzureFoundry__ImageDeploymentName": ""

6. docs/azure-foundry-setup.md — Setup Guide

Create a step-by-step guide explaining how to provision Azure AI Foundry and retrieve all required parameters to configure AzureFoundryService. The guide must cover:

  • How to create an Azure AI Foundry resource in the Azure Portal
  • How to create a project and deploy a model (chat completion + image generation)
  • How to retrieve the Endpoint URL, API Key, Deployment Name, and API Version
  • Where to store these values (App Settings / Key Vault)
  • How to switch XPoster to use AzureFoundryService via the AiProvider configuration key
  • Troubleshooting: common errors (wrong API version, missing deployment, quota limits)

Acceptance Criteria

  • AzureFoundryService implements IAiService and compiles
  • AzureFoundryOptions bound from AzureFoundry configuration section; no literals hardcoded in the service class
  • AiServiceFactory resolves AzureFoundryService when called with AiProvider.AzureFoundry
  • AiServiceFactory resolves OpenAiService when called with AiProvider.OpenAi — existing behaviour unchanged
  • GetSummaryAsync, GetImagePromptAsync, GenerateImageAsync implemented and functional
  • docs/azure-foundry-setup.md written and complete
  • All configuration keys documented in local.settings.json.example
  • Unit tests pass; CI remains green

Tests to Add

tests/Services/AzureFoundryServiceTests.cs:

GetSummaryAsync_WhenTextExceedsLimit_CallsApiAndReturnsTrimmedContent
GetSummaryAsync_WhenApiReturns429_ReturnsEmptyString
GetSummaryAsync_WhenApiReturnsNonSuccess_ReturnsEmptyString
GetImagePromptAsync_WhenApiReturnsValidResponse_ReturnsPrompt
GenerateImageAsync_WhenApiReturnsValidResponse_ReturnsByteArray
GenerateImageAsync_WhenApiReturnsNonSuccess_ReturnsEmptyByteArray

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions