feat: add cv benchmark workflow and admin visibility
This commit is contained in:
@@ -35,6 +35,7 @@ public sealed class AdminSystemController : ControllerBase
|
||||
public sealed record DatabaseStatusDto(string Provider, bool LooksConfigured, bool CanConnect, string? Target, bool UsesFileStorage, string? Warning);
|
||||
public sealed record RuntimeStatusDto(string Framework, string OSDescription, string ProcessArchitecture, string? MachineName);
|
||||
public sealed record AuthStatusDto(bool Required, bool HasJwtKey, bool GoogleConfigured, bool GmailConfigured);
|
||||
public sealed record CvBenchmarkStatusDto(string? IndexJson, string? ReportMarkdown, string RootPath, DateTimeOffset? LastUpdatedAtUtc);
|
||||
public sealed record SystemStatusDto(
|
||||
string Environment,
|
||||
string ContentRoot,
|
||||
@@ -86,6 +87,22 @@ public sealed class AdminSystemController : ControllerBase
|
||||
return Ok(await _emailSettings.UpdateAsync(request, cancellationToken));
|
||||
}
|
||||
|
||||
[HttpGet("cv-benchmark")]
|
||||
public async Task<ActionResult<CvBenchmarkStatusDto>> GetCvBenchmarkStatus(CancellationToken cancellationToken)
|
||||
{
|
||||
var indexPath = Path.Combine(_paths.CvBenchmarksRoot, "index.json");
|
||||
var reportPath = Path.Combine(_paths.CvBenchmarksRoot, "report.md");
|
||||
var indexJson = System.IO.File.Exists(indexPath) ? await System.IO.File.ReadAllTextAsync(indexPath, cancellationToken) : null;
|
||||
var reportMarkdown = System.IO.File.Exists(reportPath) ? await System.IO.File.ReadAllTextAsync(reportPath, cancellationToken) : null;
|
||||
var lastUpdated = new[]
|
||||
{
|
||||
System.IO.File.Exists(indexPath) ? System.IO.File.GetLastWriteTimeUtc(indexPath) : (DateTime?)null,
|
||||
System.IO.File.Exists(reportPath) ? System.IO.File.GetLastWriteTimeUtc(reportPath) : (DateTime?)null,
|
||||
}.Where(value => value.HasValue).Select(value => value!.Value).DefaultIfEmpty().Max();
|
||||
|
||||
return Ok(new CvBenchmarkStatusDto(indexJson, reportMarkdown, _paths.CvBenchmarksRoot, lastUpdated == default ? null : new DateTimeOffset(DateTime.SpecifyKind(lastUpdated, DateTimeKind.Utc))));
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<SystemStatusDto>> Get(CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -128,6 +145,10 @@ public sealed class AdminSystemController : ControllerBase
|
||||
OllamaReachable: null,
|
||||
OllamaModel: null,
|
||||
OllamaModelAvailable: null,
|
||||
OllamaVersion: null,
|
||||
OllamaInstalledModels: Array.Empty<string>(),
|
||||
OllamaLoadedModels: Array.Empty<string>(),
|
||||
OllamaLoadedCount: 0,
|
||||
HealthLatencyMs: null,
|
||||
ProbeLatencyMs: null,
|
||||
LastProbeAt: null,
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace JobTrackerApi.Services
|
||||
public string AttachmentsRoot { get; }
|
||||
public string CvArtifactsRoot { get; }
|
||||
public string CvExportsRoot { get; }
|
||||
public string CvBenchmarksRoot { get; }
|
||||
|
||||
public AppPaths(IConfiguration cfg, IHostEnvironment env)
|
||||
{
|
||||
@@ -39,6 +40,13 @@ namespace JobTrackerApi.Services
|
||||
|
||||
Directory.CreateDirectory(cvExportsRoot);
|
||||
CvExportsRoot = cvExportsRoot;
|
||||
|
||||
var cvBenchmarksRoot = (cfg["Data:CvBenchmarksRoot"] ?? "").Trim();
|
||||
if (string.IsNullOrWhiteSpace(cvBenchmarksRoot)) cvBenchmarksRoot = Path.Combine(DataRoot, "CvBenchmarks");
|
||||
if (!Path.IsPathRooted(cvBenchmarksRoot)) cvBenchmarksRoot = Path.Combine(env.ContentRootPath, cvBenchmarksRoot);
|
||||
|
||||
Directory.CreateDirectory(cvBenchmarksRoot);
|
||||
CvBenchmarksRoot = cvBenchmarksRoot;
|
||||
}
|
||||
|
||||
public string GetDbPath(string fileName = "jobtracker.db") => Path.Combine(DataRoot, fileName);
|
||||
|
||||
@@ -25,6 +25,10 @@ namespace JobTrackerApi.Services
|
||||
bool? OllamaReachable,
|
||||
string? OllamaModel,
|
||||
bool? OllamaModelAvailable,
|
||||
string? OllamaVersion,
|
||||
IReadOnlyList<string>? OllamaInstalledModels,
|
||||
IReadOnlyList<string>? OllamaLoadedModels,
|
||||
int? OllamaLoadedCount,
|
||||
double? HealthLatencyMs,
|
||||
double? ProbeLatencyMs,
|
||||
DateTimeOffset? LastProbeAt,
|
||||
@@ -66,6 +70,7 @@ namespace JobTrackerApi.Services
|
||||
|
||||
public interface ISummarizerService : IAiService
|
||||
{
|
||||
new Task<string?> SummarizeSectionAsync(string instruction, string text, int maxLength = 180, int minLength = 40);
|
||||
}
|
||||
|
||||
public class SummarizerService : ISummarizerService
|
||||
@@ -318,6 +323,10 @@ namespace JobTrackerApi.Services
|
||||
bool? ollamaReachable = null;
|
||||
string? ollamaModel = null;
|
||||
bool? ollamaModelAvailable = null;
|
||||
string? ollamaVersion = null;
|
||||
List<string>? ollamaInstalledModels = null;
|
||||
List<string>? ollamaLoadedModels = null;
|
||||
int? ollamaLoadedCount = null;
|
||||
double? healthLatencyMs = null;
|
||||
var healthy = false;
|
||||
string? healthError = null;
|
||||
@@ -344,6 +353,16 @@ namespace JobTrackerApi.Services
|
||||
if (doc.RootElement.TryGetProperty("ollama_reachable", out var ollamaReachableEl) && ollamaReachableEl.ValueKind is JsonValueKind.True or JsonValueKind.False) ollamaReachable = ollamaReachableEl.GetBoolean();
|
||||
if (doc.RootElement.TryGetProperty("ollama_model", out var ollamaModelEl)) ollamaModel = ollamaModelEl.GetString();
|
||||
if (doc.RootElement.TryGetProperty("ollama_model_available", out var ollamaModelAvailableEl) && ollamaModelAvailableEl.ValueKind is JsonValueKind.True or JsonValueKind.False) ollamaModelAvailable = ollamaModelAvailableEl.GetBoolean();
|
||||
if (doc.RootElement.TryGetProperty("ollama_version", out var ollamaVersionEl)) ollamaVersion = ollamaVersionEl.GetString();
|
||||
if (doc.RootElement.TryGetProperty("ollama_installed_models", out var ollamaInstalledModelsEl) && ollamaInstalledModelsEl.ValueKind == JsonValueKind.Array)
|
||||
{
|
||||
ollamaInstalledModels = ollamaInstalledModelsEl.EnumerateArray().Where(x => x.ValueKind == JsonValueKind.String).Select(x => x.GetString()).Where(x => !string.IsNullOrWhiteSpace(x)).Cast<string>().ToList();
|
||||
}
|
||||
if (doc.RootElement.TryGetProperty("ollama_loaded_models", out var ollamaLoadedModelsEl) && ollamaLoadedModelsEl.ValueKind == JsonValueKind.Array)
|
||||
{
|
||||
ollamaLoadedModels = ollamaLoadedModelsEl.EnumerateArray().Where(x => x.ValueKind == JsonValueKind.String).Select(x => x.GetString()).Where(x => !string.IsNullOrWhiteSpace(x)).Cast<string>().ToList();
|
||||
}
|
||||
if (doc.RootElement.TryGetProperty("ollama_loaded_count", out var ollamaLoadedCountEl) && ollamaLoadedCountEl.ValueKind == JsonValueKind.Number) ollamaLoadedCount = ollamaLoadedCountEl.GetInt32();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -406,6 +425,10 @@ namespace JobTrackerApi.Services
|
||||
OllamaReachable: ollamaReachable,
|
||||
OllamaModel: ollamaModel,
|
||||
OllamaModelAvailable: ollamaModelAvailable,
|
||||
OllamaVersion: ollamaVersion,
|
||||
OllamaInstalledModels: ollamaInstalledModels,
|
||||
OllamaLoadedModels: ollamaLoadedModels,
|
||||
OllamaLoadedCount: ollamaLoadedCount,
|
||||
HealthLatencyMs: healthLatencyMs,
|
||||
ProbeLatencyMs: probeLatencyMs,
|
||||
LastProbeAt: lastProbeAt,
|
||||
|
||||
Reference in New Issue
Block a user