feat: Enhance Authority Identity Provider Registry with Bootstrap Capability
- Added support for bootstrap providers in AuthorityIdentityProviderRegistry. - Introduced a new property for bootstrap providers and updated AggregateCapabilities. - Updated relevant methods to handle bootstrap capabilities during provider registration. feat: Introduce Sealed Mode Status in OpenIddict Handlers - Added SealedModeStatusProperty to AuthorityOpenIddictConstants. - Enhanced ValidateClientCredentialsHandler, ValidatePasswordGrantHandler, and ValidateRefreshTokenGrantHandler to validate sealed mode evidence. - Implemented logic to handle airgap seal confirmation requirements. feat: Update Program Configuration for Sealed Mode - Registered IAuthoritySealedModeEvidenceValidator in Program.cs. - Added logging for bootstrap capabilities in identity provider plugins. - Implemented checks for bootstrap support in API endpoints. chore: Update Tasks and Documentation - Marked AUTH-MTLS-11-002 as DONE in TASKS.md. - Updated documentation to reflect changes in sealed mode and bootstrap capabilities. fix: Improve CLI Command Handlers Output - Enhanced output formatting for command responses and prompts in CommandHandlers.cs. feat: Extend Advisory AI Models - Added Response property to AdvisoryPipelineOutputModel for better output handling. fix: Adjust Concelier Web Service Authentication - Improved JWT token handling in Concelier Web Service to ensure proper token extraction and logging. test: Enhance Web Service Endpoints Tests - Added detailed logging for authentication failures in WebServiceEndpointsTests. - Enabled PII logging for better debugging of authentication issues. feat: Introduce Air-Gap Configuration Options - Added AuthorityAirGapOptions and AuthoritySealedModeOptions to StellaOpsAuthorityOptions. - Implemented validation logic for air-gap configurations to ensure proper setup.
This commit is contained in:
@@ -14,6 +14,7 @@ using StellaOps.AdvisoryAI.Prompting;
|
||||
using StellaOps.AdvisoryAI.Queue;
|
||||
using StellaOps.AdvisoryAI.Metrics;
|
||||
using StellaOps.AdvisoryAI.Tools;
|
||||
using StellaOps.AdvisoryAI.Inference;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.AdvisoryAI.Tests;
|
||||
@@ -30,7 +31,8 @@ public sealed class AdvisoryPipelineExecutorTests : IDisposable
|
||||
var guardrail = new StubGuardrailPipeline(blocked: false);
|
||||
var store = new InMemoryAdvisoryOutputStore();
|
||||
using var metrics = new AdvisoryPipelineMetrics(_meterFactory);
|
||||
var executor = new AdvisoryPipelineExecutor(assembler, guardrail, store, metrics, TimeProvider.System);
|
||||
var inference = new StubInferenceClient();
|
||||
var executor = new AdvisoryPipelineExecutor(assembler, guardrail, store, metrics, TimeProvider.System, inference);
|
||||
|
||||
var message = new AdvisoryTaskQueueMessage(plan.CacheKey, plan.Request);
|
||||
await executor.ExecuteAsync(plan, message, planFromCache: false, CancellationToken.None);
|
||||
@@ -43,6 +45,7 @@ public sealed class AdvisoryPipelineExecutorTests : IDisposable
|
||||
saved.Provenance.InputDigest.Should().Be(plan.CacheKey);
|
||||
saved.Provenance.OutputHash.Should().NotBeNullOrWhiteSpace();
|
||||
saved.Prompt.Should().Be("{\"prompt\":\"value\"}");
|
||||
saved.Response.Should().Be("{\"prompt\":\"value\"}");
|
||||
saved.Guardrail.Metadata.Should().ContainKey("prompt_length");
|
||||
}
|
||||
|
||||
@@ -54,7 +57,8 @@ public sealed class AdvisoryPipelineExecutorTests : IDisposable
|
||||
var guardrail = new StubGuardrailPipeline(blocked: true);
|
||||
var store = new InMemoryAdvisoryOutputStore();
|
||||
using var metrics = new AdvisoryPipelineMetrics(_meterFactory);
|
||||
var executor = new AdvisoryPipelineExecutor(assembler, guardrail, store, metrics, TimeProvider.System);
|
||||
var inference = new StubInferenceClient();
|
||||
var executor = new AdvisoryPipelineExecutor(assembler, guardrail, store, metrics, TimeProvider.System, inference);
|
||||
|
||||
var message = new AdvisoryTaskQueueMessage(plan.CacheKey, plan.Request);
|
||||
await executor.ExecuteAsync(plan, message, planFromCache: true, CancellationToken.None);
|
||||
@@ -84,12 +88,12 @@ public sealed class AdvisoryPipelineExecutorTests : IDisposable
|
||||
|
||||
listener.SetMeasurementEventCallback<double>((instrument, measurement, tags, state) =>
|
||||
{
|
||||
doubleMeasurements.Add((instrument.Name, measurement, tags));
|
||||
doubleMeasurements.Add((instrument.Name, measurement, tags.ToArray()));
|
||||
});
|
||||
|
||||
listener.SetMeasurementEventCallback<long>((instrument, measurement, tags, state) =>
|
||||
{
|
||||
longMeasurements.Add((instrument.Name, measurement, tags));
|
||||
longMeasurements.Add((instrument.Name, measurement, tags.ToArray()));
|
||||
});
|
||||
|
||||
listener.Start();
|
||||
@@ -99,7 +103,8 @@ public sealed class AdvisoryPipelineExecutorTests : IDisposable
|
||||
var guardrail = new StubGuardrailPipeline(blocked: true);
|
||||
var store = new InMemoryAdvisoryOutputStore();
|
||||
using var metrics = new AdvisoryPipelineMetrics(_meterFactory);
|
||||
var executor = new AdvisoryPipelineExecutor(assembler, guardrail, store, metrics, TimeProvider.System);
|
||||
var inference = new StubInferenceClient();
|
||||
var executor = new AdvisoryPipelineExecutor(assembler, guardrail, store, metrics, TimeProvider.System, inference);
|
||||
|
||||
var message = new AdvisoryTaskQueueMessage(plan.CacheKey, plan.Request);
|
||||
await executor.ExecuteAsync(plan, message, planFromCache: false, CancellationToken.None);
|
||||
@@ -135,7 +140,7 @@ public sealed class AdvisoryPipelineExecutorTests : IDisposable
|
||||
|
||||
listener.SetMeasurementEventCallback<double>((instrument, measurement, tags, state) =>
|
||||
{
|
||||
doubleMeasurements.Add((instrument.Name, measurement, tags));
|
||||
doubleMeasurements.Add((instrument.Name, measurement, tags.ToArray()));
|
||||
});
|
||||
|
||||
listener.Start();
|
||||
@@ -145,7 +150,8 @@ public sealed class AdvisoryPipelineExecutorTests : IDisposable
|
||||
var guardrail = new StubGuardrailPipeline(blocked: false);
|
||||
var store = new InMemoryAdvisoryOutputStore();
|
||||
using var metrics = new AdvisoryPipelineMetrics(_meterFactory);
|
||||
var executor = new AdvisoryPipelineExecutor(assembler, guardrail, store, metrics, TimeProvider.System);
|
||||
var inference = new StubInferenceClient();
|
||||
var executor = new AdvisoryPipelineExecutor(assembler, guardrail, store, metrics, TimeProvider.System, inference);
|
||||
|
||||
var message = new AdvisoryTaskQueueMessage(plan.CacheKey, plan.Request);
|
||||
await executor.ExecuteAsync(plan, message, planFromCache: false, CancellationToken.None);
|
||||
@@ -289,6 +295,18 @@ public sealed class AdvisoryPipelineExecutorTests : IDisposable
|
||||
=> Task.FromResult(_result);
|
||||
}
|
||||
|
||||
private sealed class StubInferenceClient : IAdvisoryInferenceClient
|
||||
{
|
||||
public AdvisoryInferenceResult Result { get; set; } = AdvisoryInferenceResult.FromLocal("{\"prompt\":\"value\"}");
|
||||
|
||||
public Task<AdvisoryInferenceResult> GenerateAsync(
|
||||
AdvisoryTaskPlan plan,
|
||||
AdvisoryPrompt prompt,
|
||||
AdvisoryGuardrailResult guardrailResult,
|
||||
CancellationToken cancellationToken)
|
||||
=> Task.FromResult(Result);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_meterFactory.Dispose();
|
||||
|
||||
@@ -73,7 +73,7 @@ public sealed class ConcelierAdvisoryDocumentProviderTests
|
||||
|
||||
public Task<IReadOnlyList<AdvisoryRawRecord>> FindByAdvisoryKeyAsync(
|
||||
string tenant,
|
||||
IReadOnlyCollection<string> searchValues,
|
||||
string advisoryKey,
|
||||
IReadOnlyCollection<string> sourceVendors,
|
||||
CancellationToken cancellationToken)
|
||||
=> Task.FromResult(_records);
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StellaOps.AdvisoryAI.Abstractions;
|
||||
using StellaOps.AdvisoryAI.Caching;
|
||||
using StellaOps.AdvisoryAI.Context;
|
||||
using StellaOps.AdvisoryAI.Documents;
|
||||
@@ -14,6 +15,7 @@ using StellaOps.AdvisoryAI.Guardrails;
|
||||
using StellaOps.AdvisoryAI.Hosting;
|
||||
using StellaOps.AdvisoryAI.Outputs;
|
||||
using StellaOps.AdvisoryAI.Orchestration;
|
||||
using StellaOps.AdvisoryAI.Prompting;
|
||||
using StellaOps.AdvisoryAI.Tools;
|
||||
using Xunit;
|
||||
|
||||
@@ -67,11 +69,13 @@ public sealed class FileSystemAdvisoryPersistenceTests : IDisposable
|
||||
var plan = CreatePlan("cache-abc");
|
||||
var prompt = "{\"prompt\":\"value\"}";
|
||||
var guardrail = AdvisoryGuardrailResult.Allowed(prompt);
|
||||
var response = "response-text";
|
||||
var output = new AdvisoryPipelineOutput(
|
||||
plan.CacheKey,
|
||||
plan.Request.TaskType,
|
||||
plan.Request.Profile,
|
||||
prompt,
|
||||
response,
|
||||
ImmutableArray.Create(new AdvisoryPromptCitation(1, "doc-1", "chunk-1")),
|
||||
ImmutableDictionary<string, string>.Empty.Add("advisory_key", plan.Request.AdvisoryKey),
|
||||
guardrail,
|
||||
@@ -84,6 +88,7 @@ public sealed class FileSystemAdvisoryPersistenceTests : IDisposable
|
||||
|
||||
reloaded.Should().NotBeNull();
|
||||
reloaded!.Prompt.Should().Be(prompt);
|
||||
reloaded.Response.Should().Be(response);
|
||||
reloaded.Metadata.Should().ContainKey("advisory_key").WhoseValue.Should().Be(plan.Request.AdvisoryKey);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user