# Anthropic

## Description

The Anthropic provider integrates Claude chat behind `IFlexAIProvider`.

Provider capabilities (based on the implementation):

* Chat completions: `ChatAsync(...)`
* Streaming chat: `ChatStreamAsync(...)`
* Embeddings: **not supported** (`EmbedAsync(...)` throws `NotSupportedException`)

## Important concepts

* Application code should depend on `IFlexAIProvider`.
* Flex generates Queries/Handlers that consume `IFlexAIProvider`; you only register the provider.
* Default chat model (when not overridden by request/config): `claude-3-5-sonnet-20241022`

Implementation note: token usage is estimated when the provider does not return concrete usage counts.

## Configuration in DI

```csharp
services.AddFlexAnthropic(configuration);
```

## appsettings.json

Configuration section: `FlexBase:AI:Anthropic`

```json
{
  "FlexBase": {
	"AI": {
	  "Anthropic": {
		"ApiKey": "<store-in-secrets>",
		"DefaultModel": "claude-3-5-sonnet-20241022",
		"MaxTokens": 4096,
		"Timeout": "00:02:00"
	  }
	}
  }
}
```

## Examples (template-based)

These examples mirror the generated Query and PostBus handler templates. You do **not** register these types manually.

### Query: generate a completion

```csharp
using Microsoft.Extensions.Logging;
using Sumeru.Flex;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace {YourApplication}.Queries.AI;

public class GenerateChatCompletionGetSingle : FlexiQueryBridgeAsync<ChatCompletionDto>
{
	protected readonly ILogger<GenerateChatCompletionGetSingle> _logger;
	protected readonly IFlexHost _flexHost;
	protected readonly IFlexAIProvider _aiProvider;
	protected FlexAppContextBridge _flexAppContext;
	protected GenerateChatCompletionParams _params;

	public GenerateChatCompletionGetSingle(
		ILogger<GenerateChatCompletionGetSingle> logger,
		IFlexHost flexHost,
		IFlexAIProvider aiProvider)
	{
		_logger = logger;
		_flexHost = flexHost;
		_aiProvider = aiProvider;
	}

	public virtual GenerateChatCompletionGetSingle AssignParameters(GenerateChatCompletionParams @params)
	{
		_params = @params;
		return this;
	}

	public virtual async Task<ChatCompletionDto?> Fetch()
	{
		_flexAppContext = _params.GetAppContext();

		var response = await _aiProvider.ChatAsync(new FlexAIChatRequest
		{
			Model = _params.Model,
			Messages = _params.Messages,
			Temperature = _params.Temperature,
			MaxTokens = _params.MaxTokens
		});

		return new ChatCompletionDto { Response = response.Message.Content };
	}
}

public class GenerateChatCompletionParams : DtoBridge
{
	public string? Model { get; set; }
	public List<FlexAIMessage> Messages { get; set; } = new();
	public float? Temperature { get; set; }
	public int? MaxTokens { get; set; }
}

public class ChatCompletionDto : DtoBridge
{
	public string Response { get; set; }
}
```

### PostBus handler: generate a completion

```csharp
using Microsoft.Extensions.Logging;
using Sumeru.Flex;
using System.Threading.Tasks;

namespace {YourApplication}.PostBusHandlers.AI;

public partial class GenerateChatCompletionHandler : IGenerateChatCompletionHandler
{
	protected string EventCondition = string.Empty;
	protected readonly ILogger<GenerateChatCompletionHandler> _logger;
	protected readonly IFlexHost _flexHost;
	protected readonly IFlexAIProvider _aiProvider;

	protected FlexAppContextBridge? _flexAppContext;

	public GenerateChatCompletionHandler(
		ILogger<GenerateChatCompletionHandler> logger,
		IFlexHost flexHost,
		IFlexAIProvider aiProvider)
	{
		_logger = logger;
		_flexHost = flexHost;
		_aiProvider = aiProvider;
	}

	public virtual async Task Execute(GenerateChatCompletionCommand cmd, IFlexServiceBusContext serviceBusContext)
	{
		_flexAppContext = cmd.Dto.GetAppContext();  //do not remove this line

		var response = await _aiProvider.ChatAsync(new FlexAIChatRequest
		{
			Model = cmd.Dto.Model,
			Messages = cmd.Dto.Messages,
			Temperature = cmd.Dto.Temperature,
			MaxTokens = cmd.Dto.MaxTokens
		});

		cmd.Dto.Response = response.Message.Content;
		await this.Fire(EventCondition, serviceBusContext);
	}
}
```

## Provider considerations

* **Embeddings**: not supported; pair Anthropic with OpenAI/Azure OpenAI/Gemini/Ollama for embedding generation.
* **Max tokens**: keep `MaxTokens` conservative to avoid truncation or request failures.
* **Streaming**: prefer streaming for UI responsiveness and long completions.
