feat(scanner): Implement Deno analyzer and associated tests
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Added Deno analyzer with comprehensive metadata and evidence structure. - Created a detailed implementation plan for Sprint 130 focusing on Deno analyzer. - Introduced AdvisoryAiGuardrailOptions for managing guardrail configurations. - Developed GuardrailPhraseLoader for loading blocked phrases from JSON files. - Implemented tests for AdvisoryGuardrailOptions binding and phrase loading. - Enhanced telemetry for Advisory AI with metrics tracking. - Added VexObservationProjectionService for querying VEX observations. - Created extensive tests for VexObservationProjectionService functionality. - Introduced Ruby language analyzer with tests for simple and complex workspaces. - Added Ruby application fixtures for testing purposes.
This commit is contained in:
@@ -1,13 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Headers;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StellaOps.AdvisoryAI.Caching;
|
||||
using StellaOps.AdvisoryAI.DependencyInjection;
|
||||
using StellaOps.AdvisoryAI.Inference;
|
||||
using StellaOps.AdvisoryAI.Metrics;
|
||||
using StellaOps.AdvisoryAI.Guardrails;
|
||||
using StellaOps.AdvisoryAI.Outputs;
|
||||
using StellaOps.AdvisoryAI.Providers;
|
||||
using StellaOps.AdvisoryAI.Queue;
|
||||
@@ -86,6 +91,12 @@ public static class ServiceCollectionExtensions
|
||||
services.AddAdvisoryPipeline();
|
||||
services.AddAdvisoryPipelineInfrastructure();
|
||||
|
||||
services.AddOptions<AdvisoryGuardrailOptions>()
|
||||
.Configure<IOptions<AdvisoryAiServiceOptions>, IHostEnvironment>((options, aiOptions, environment) =>
|
||||
{
|
||||
ApplyGuardrailConfiguration(options, aiOptions.Value.Guardrails, environment);
|
||||
});
|
||||
|
||||
services.Replace(ServiceDescriptor.Singleton<IAdvisoryTaskQueue, FileSystemAdvisoryTaskQueue>());
|
||||
services.Replace(ServiceDescriptor.Singleton<IAdvisoryPlanCache, FileSystemAdvisoryPlanCache>());
|
||||
services.Replace(ServiceDescriptor.Singleton<IAdvisoryOutputStore, FileSystemAdvisoryOutputStore>());
|
||||
@@ -93,4 +104,87 @@ public static class ServiceCollectionExtensions
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
private static void ApplyGuardrailConfiguration(
|
||||
AdvisoryGuardrailOptions target,
|
||||
AdvisoryAiGuardrailOptions? source,
|
||||
IHostEnvironment? environment)
|
||||
{
|
||||
if (source is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (source.MaxPromptLength.HasValue && source.MaxPromptLength.Value > 0)
|
||||
{
|
||||
target.MaxPromptLength = source.MaxPromptLength.Value;
|
||||
}
|
||||
|
||||
target.RequireCitations = source.RequireCitations;
|
||||
|
||||
var defaults = target.BlockedPhrases.ToList();
|
||||
var merged = new SortedSet<string>(defaults, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
if (source.BlockedPhrases is { Count: > 0 })
|
||||
{
|
||||
foreach (var phrase in source.BlockedPhrases)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(phrase))
|
||||
{
|
||||
merged.Add(phrase.Trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(source.BlockedPhraseFile))
|
||||
{
|
||||
var resolvedPath = ResolveGuardrailPath(source.BlockedPhraseFile!, environment);
|
||||
foreach (var phrase in GuardrailPhraseLoader.Load(resolvedPath))
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(phrase))
|
||||
{
|
||||
merged.Add(phrase.Trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (merged.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
target.BlockedPhrases.Clear();
|
||||
foreach (var phrase in merged)
|
||||
{
|
||||
target.BlockedPhrases.Add(phrase);
|
||||
}
|
||||
}
|
||||
|
||||
private static string ResolveGuardrailPath(string configuredPath, IHostEnvironment? environment)
|
||||
{
|
||||
var trimmed = configuredPath.Trim();
|
||||
if (Path.IsPathRooted(trimmed))
|
||||
{
|
||||
if (!File.Exists(trimmed))
|
||||
{
|
||||
throw new FileNotFoundException($"Guardrail phrase file {trimmed} was not found.", trimmed);
|
||||
}
|
||||
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
var root = environment?.ContentRootPath;
|
||||
if (string.IsNullOrWhiteSpace(root))
|
||||
{
|
||||
root = AppContext.BaseDirectory;
|
||||
}
|
||||
|
||||
var resolved = Path.GetFullPath(Path.Combine(root!, trimmed));
|
||||
if (!File.Exists(resolved))
|
||||
{
|
||||
throw new FileNotFoundException($"Guardrail phrase file {resolved} was not found.", resolved);
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user