Skip to content

Configuration

Strategos integrates with proven .NET infrastructure. This reference covers setup and configuration for each integration.

IntegrationPurposeRequired
WolverineSaga orchestration, message routing, transactional outboxYes
MartenEvent sourcing, projections, time-travel queriesYes
PostgreSQLPersistence for both Wolverine and MartenYes
Microsoft.Extensions.AILLM integration via IChatClientFor AI workflows

Wolverine provides saga orchestration for workflow execution.

Every workflow definition is compiled into a Wolverine saga at build time:

Workflow Definition -> Source Generator -> Wolverine Saga
(DSL) (compile-time) (runtime)

The source generator produces:

  • A saga class with [SagaIdentity] for workflow instance tracking
  • Command handlers for each step transition
  • Automatic message cascading between steps
// Generated command for a step
public record ExecuteProcessPaymentCommand(
[property: SagaIdentity] Guid WorkflowId);
// Handler in the saga
public async Task<ExecuteFulfillOrderCommand> Handle(
ExecuteProcessPaymentCommand command,
ProcessPayment step,
CancellationToken ct)
{
var result = await step.ExecuteAsync(State, ct);
State = StateReducer.Reduce(State, result.StateUpdate);
return new ExecuteFulfillOrderCommand(WorkflowId);
}

Wolverine’s transactional outbox ensures state updates and outgoing messages are committed atomically. If a process crashes after updating state but before sending the next message, the message is recovered from the outbox on restart.

services.AddWolverine(opts =>
{
opts.Handlers.OnException<HttpRequestException>()
.RetryWithCooldown(100.Milliseconds(), 500.Milliseconds(), 1.Seconds());
});

Marten provides event sourcing and projections.

EventWhen Emitted
WorkflowStartedWorkflow instance created
PhaseChangedTransition between phases
StepCompletedStep finished executing
BranchTakenRouting decision made
ApprovalRequestedWorkflow paused for human input
ApprovalReceivedHuman input received
WorkflowCompletedWorkflow reached terminal state
session.Events.Append(
workflowId,
new PhaseChanged(workflowId, fromPhase, toPhase, timestamp));

Reconstruct state at any point in history:

// Get state at a specific version
var historicalState = await session.Events
.AggregateStreamAsync<WorkflowState>(
workflowId,
version: 5);
// Get state at a specific timestamp
var historicalState = await session.Events
.AggregateStreamAsync<WorkflowState>(
workflowId,
timestamp: specificTime);

Query workflows by phase or other criteria:

var awaitingApproval = await session
.Query<WorkflowReadModel>()
.Where(w => w.CurrentPhase == Phase.AwaitingApproval)
.ToListAsync();

Both Wolverine and Marten use PostgreSQL as their persistence layer.

Table/SchemaContent
wolverine_*Saga state, outbox messages, dead letters
mt_eventsEvent streams (append-only)
mt_doc_*Document projections (read models)
mt_streamsStream metadata and version tracking
var connectionString = builder.Configuration.GetConnectionString("Postgres");
services.AddMarten(opts =>
{
opts.Connection(connectionString);
});
services.AddWolverineWithMarten(opts =>
{
opts.PersistenceConnection(connectionString);
});

Integration for LLM-powered workflow steps.

public class AnalyzeStep : IAgentStep<DocumentState>
{
private readonly IChatClient _chatClient;
public AnalyzeStep(IChatClient chatClient)
{
_chatClient = chatClient;
}
public async Task<StepResult<DocumentState>> ExecuteAsync(
DocumentState state,
AgentStepContext context,
CancellationToken ct)
{
var response = await _chatClient.GetResponseAsync(
$"Analyze: {state.Content}",
ct);
return state.With(s => s.Analysis, response).AsResult();
}
}
ProviderPackage
OpenAIMicrosoft.Extensions.AI.OpenAI
Azure OpenAIMicrosoft.Extensions.AI.AzureOpenAI
OllamaOllamaChatClient
CustomImplement IChatClient
public class StreamingStep : IAgentStep<ChatState>
{
public async Task<StepResult<ChatState>> ExecuteAsync(
ChatState state,
AgentStepContext context,
CancellationToken ct)
{
await foreach (var chunk in _chatClient.GetStreamingResponseAsync(...))
{
context.StreamingCallback?.OnToken(chunk.Text);
}
// ...
}
}

Full configuration with all integrations:

var builder = WebApplication.CreateBuilder(args);
// PostgreSQL connection
var connectionString = builder.Configuration.GetConnectionString("Postgres");
// Marten (event sourcing)
builder.Services.AddMarten(opts =>
{
opts.Connection(connectionString);
opts.AutoCreateSchemaObjects = AutoCreate.All;
});
// Wolverine (saga orchestration)
builder.Services.AddWolverineWithMarten(opts =>
{
opts.PersistenceConnection(connectionString);
});
// Microsoft.Extensions.AI (LLM integration)
builder.Services.AddSingleton<IChatClient>(
new OpenAIChatClient("gpt-4o", apiKey));
// Strategos
builder.Services.AddStrategos()
.AddWorkflow<ProcessOrderWorkflow>()
.AddThompsonSampling()
.AddLoopDetection()
.AddBudgetGuard();

Status: Planned for Strategos.Rag

Will provide PgVectorAdapter implementing IVectorSearchAdapter for vector similarity search using the same PostgreSQL database.

Status: Planned for Strategos.Rag

Will provide AzureAISearchAdapter for enterprise-scale vector and hybrid search.