Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Unity.GrantManager.AI
{
public class AIAttachmentPromptItem
{
public string Name { get; set; } = string.Empty;
public string Summary { get; set; } = string.Empty;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Unity.GrantManager.AI
{
public class AICompletionRequest
{
public string UserPrompt { get; set; } = string.Empty;
public string? SystemPrompt { get; set; }
public int MaxTokens { get; set; } = 150;
public double? Temperature { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace Unity.GrantManager.AI
{
public static class AIJsonKeys
{
public const string Rating = "rating";
public const string Errors = "errors";
public const string Warnings = "warnings";
public const string Summaries = "summaries";
public const string Dismissed = "dismissed";

public const string Id = "id";
public const string Title = "title";
public const string Detail = "detail";
public const string Summary = "summary";

public const string Answer = "answer";
public const string Rationale = "rationale";
public const string Confidence = "confidence";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Collections.Generic;
using System.Text.Json;

namespace Unity.GrantManager.AI
{
public class ApplicationAnalysisRequest
{
public JsonElement Schema { get; set; }
public JsonElement Data { get; set; }
public List<ApplicationAnalysisAttachment> Attachments { get; set; } = new();
public string? Rubric { get; set; }
}

public class ApplicationAnalysisAttachment
{
public string Name { get; set; } = string.Empty;
public string Summary { get; set; } = string.Empty;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace Unity.GrantManager.AI
{
public class ApplicationAnalysisResponse
{
[JsonPropertyName(AIJsonKeys.Rating)]
public string? Rating { get; set; }

[JsonPropertyName(AIJsonKeys.Errors)]
public List<ApplicationAnalysisFinding> Errors { get; set; } = new();

[JsonPropertyName(AIJsonKeys.Warnings)]
public List<ApplicationAnalysisFinding> Warnings { get; set; } = new();

[JsonPropertyName(AIJsonKeys.Summaries)]
public List<ApplicationAnalysisFinding> Summaries { get; set; } = new();

[JsonPropertyName(AIJsonKeys.Dismissed)]
public List<string> Dismissed { get; set; } = new();
}

public class ApplicationAnalysisFinding
{
[JsonPropertyName(AIJsonKeys.Id)]
public string? Id { get; set; }

[JsonPropertyName(AIJsonKeys.Title)]
public string? Title { get; set; }

[JsonPropertyName(AIJsonKeys.Detail)]
public string? Detail { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Unity.GrantManager.AI
{
public class AttachmentSummaryRequest
{
public string FileName { get; set; } = string.Empty;
public byte[] FileContent { get; set; } = System.Array.Empty<byte>();
public string ContentType { get; set; } = "application/octet-stream";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@ namespace Unity.GrantManager.AI
public interface IAIService
{
Task<bool> IsAvailableAsync();
Task<string> GenerateSummaryAsync(string content, string? prompt = null, int maxTokens = 150);

Task<string> GenerateCompletionAsync(AICompletionRequest request);
Task<string> GenerateAttachmentSummaryAsync(AttachmentSummaryRequest request);
Task<string> GenerateAttachmentSummaryAsync(string fileName, byte[] fileContent, string contentType);
Task<string> GenerateApplicationAnalysisAsync(ApplicationAnalysisRequest request);
Task<string> GenerateScoresheetSectionAnswersAsync(ScoresheetSectionRequest request);
Task<string> GenerateScoresheetSectionAnswersAsync(string applicationContent, List<string> attachmentSummaries, string sectionJson, string sectionName);

// Legacy compatibility methods retained until flow orchestration refactor.
Task<string> GenerateSummaryAsync(string content, string? prompt = null, int maxTokens = 150);
Task<string> AnalyzeApplicationAsync(string applicationContent, List<string> attachmentSummaries, string rubric, string? formFieldConfiguration = null);
Task<string> GenerateScoresheetAnswersAsync(string applicationContent, List<string> attachmentSummaries, string scoresheetQuestions);
Task<string> GenerateScoresheetSectionAnswersAsync(string applicationContent, List<string> attachmentSummaries, string sectionJson, string sectionName);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Collections.Generic;
using System.Text.Json;

namespace Unity.GrantManager.AI
{
public class ScoresheetSectionRequest
{
public JsonElement Data { get; set; }
public List<AIAttachmentPromptItem> Attachments { get; set; } = new();
public string SectionName { get; set; } = string.Empty;
public JsonElement SectionSchema { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Unity.GrantManager.AI;
using Unity.GrantManager.ApplicationForms;
using Volo.Abp.Application.Dtos;

Expand Down Expand Up @@ -83,4 +84,5 @@ public class GrantApplicationDto : AuditedEntityDto<Guid>
public string? UnityApplicationId { get; set; }
public string? ApplicantElectoralDistrict { get; set; }
public string? AIAnalysis { get; set; }
public ApplicationAnalysisResponse? AIAnalysisData { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,36 @@ public Task<bool> IsAvailableAsync()
return Task.FromResult(true);
}

public Task<string> GenerateCompletionAsync(AICompletionRequest request)
{
return GenerateSummaryAsync(
request?.UserPrompt ?? string.Empty,
request?.SystemPrompt,
request?.MaxTokens ?? 150);
}

public Task<string> GenerateApplicationAnalysisAsync(ApplicationAnalysisRequest request)
{
var dataJson = JsonSerializer.Serialize(request.Data, JsonLogOptions);
var schemaJson = JsonSerializer.Serialize(request.Schema, JsonLogOptions);

var attachmentSummaries = request.Attachments
.Select(a => $"{a.Name}: {a.Summary}")
.ToList();

var applicationContent = $@"DATA
{dataJson}";

var formFieldConfiguration = $@"SCHEMA
{schemaJson}";

return AnalyzeApplicationAsync(
applicationContent,
attachmentSummaries,
request.Rubric ?? string.Empty,
formFieldConfiguration);
}

public async Task<string> GenerateSummaryAsync(string content, string? prompt = null, int maxTokens = 150)
{
if (string.IsNullOrEmpty(ApiKey))
Expand Down Expand Up @@ -177,6 +207,14 @@ Produce a concise reviewer-facing summary of the provided attachment context.
}
}

public Task<string> GenerateAttachmentSummaryAsync(AttachmentSummaryRequest request)
{
return GenerateAttachmentSummaryAsync(
request?.FileName ?? string.Empty,
request?.FileContent ?? Array.Empty<byte>(),
request?.ContentType ?? "application/octet-stream");
}

public async Task<string> AnalyzeApplicationAsync(string applicationContent, List<string> attachmentSummaries, string rubric, string? formFieldConfiguration = null)
{
if (string.IsNullOrEmpty(ApiKey))
Expand Down Expand Up @@ -512,6 +550,22 @@ public async Task<string> GenerateScoresheetSectionAnswersAsync(string applicati
}
}

public Task<string> GenerateScoresheetSectionAnswersAsync(ScoresheetSectionRequest request)
{
var dataJson = JsonSerializer.Serialize(request.Data, JsonLogOptions);
var sectionJson = JsonSerializer.Serialize(request.SectionSchema, JsonLogOptions);

var attachmentSummaries = request.Attachments
.Select(a => $"{a.Name}: {a.Summary}")
.ToList();

return GenerateScoresheetSectionAnswersAsync(
dataJson,
attachmentSummaries,
sectionJson,
request.SectionName);
}

private async Task LogPromptInputAsync(string promptType, string? systemPrompt, string userPrompt)
{
var formattedInput = FormatPromptInputForLog(systemPrompt, userPrompt);
Expand Down
Loading