117 lines
4.8 KiB
C#
117 lines
4.8 KiB
C#
using System.Net;
|
|
using System.Text.Json;
|
|
using Microsoft.Azure.Functions.Worker;
|
|
using Microsoft.Azure.Functions.Worker.Http;
|
|
using Microsoft.Extensions.Logging;
|
|
using Google.GenAI;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace CognitiveClarity.api
|
|
{
|
|
public class AnalysisRequest
|
|
{
|
|
[JsonPropertyName("turnContext")]
|
|
public string TurnContext { get; set; } = string.Empty;
|
|
|
|
[JsonPropertyName("scenarioTitle")]
|
|
public string ScenarioTitle { get; set; } = string.Empty;
|
|
|
|
[JsonPropertyName("scenarioDescription")]
|
|
public string ScenarioDescription { get; set; } = string.Empty;
|
|
|
|
[JsonPropertyName("cbtFocus")]
|
|
public List<string> CBTFocus { get; set; } = new();
|
|
}
|
|
|
|
public class AnalysisFunction
|
|
{
|
|
private readonly ILogger _logger;
|
|
|
|
public AnalysisFunction(ILoggerFactory loggerFactory)
|
|
{
|
|
_logger = loggerFactory.CreateLogger<AnalysisFunction>();
|
|
}
|
|
|
|
[Function("ClinicalAnalysis")]
|
|
public async Task<HttpResponseData> Run(
|
|
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "analysis")] HttpRequestData req)
|
|
{
|
|
_logger.LogInformation("C# HTTP trigger function processed a clinical analysis request.");
|
|
|
|
var requestBody = await new StreamReader(req.Body).ReadToEndAsync();
|
|
var data = JsonSerializer.Deserialize<AnalysisRequest>(requestBody);
|
|
|
|
if (data == null || string.IsNullOrWhiteSpace(data.TurnContext))
|
|
{
|
|
var badResponse = req.CreateResponse(HttpStatusCode.BadRequest);
|
|
await badResponse.WriteStringAsync("Please provide turnContext in the request body");
|
|
return badResponse;
|
|
}
|
|
|
|
var apiKey = Environment.GetEnvironmentVariable("GEMINI_API_KEY");
|
|
if (string.IsNullOrEmpty(apiKey))
|
|
{
|
|
_logger.LogError("GEMINI_API_KEY is missing from environment variables.");
|
|
return req.CreateResponse(HttpStatusCode.InternalServerError);
|
|
}
|
|
|
|
// Initialize the Gemini Client
|
|
var ai = new GeminiClient(apiKey: apiKey);
|
|
|
|
var systemAnalysisPrompt = @"
|
|
You are a master clinical psychologist specializing in Cognitive Behavioral Therapy (CBT).
|
|
You are observing a roleplay session between a user and an AI character.
|
|
Analyze the user's latest response for:
|
|
1. Cognitive distortions present (if any).
|
|
2. CBT techniques successfully applied by the user (if any).
|
|
3. A brief, encouraging clinical insight or redirection (max 2 sentences).
|
|
Be precise, clinical, and constructive.
|
|
";
|
|
|
|
var analysisSystemInstruction = $@"{systemAnalysisPrompt}
|
|
SCENARIO CONTEXT:
|
|
Title: {data.ScenarioTitle}
|
|
Description: {data.ScenarioDescription}
|
|
CBT Focus Areas: {string.Join(", ", data.CBTFocus)}";
|
|
|
|
var schema = new Schema
|
|
{
|
|
Type = TypeEnum.Object,
|
|
Properties = new Dictionary<string, Schema>
|
|
{
|
|
{ "distortionsIdentified", new Schema { Type = TypeEnum.Array, Items = new Schema { Type = TypeEnum.String } } },
|
|
{ "techniquesUsed", new Schema { Type = TypeEnum.Array, Items = new Schema { Type = TypeEnum.String } } },
|
|
{ "clinicalInsight", new Schema { Type = TypeEnum.String } },
|
|
{ "feedbackType", new Schema { Type = TypeEnum.String, Enum = new List<string> { "Constructive", "Positive", "Neutral" } } }
|
|
},
|
|
Required = new List<string> { "distortionsIdentified", "techniquesUsed", "clinicalInsight", "feedbackType" }
|
|
};
|
|
|
|
try
|
|
{
|
|
var response = await ai.Models.GenerateContentAsync(
|
|
model: "gemini-3.0-flash",
|
|
contents: data.TurnContext,
|
|
new GenerateContentConfig
|
|
{
|
|
SystemInstruction = new Content { Parts = new List<Part> { new Part { Text = analysisSystemInstruction } } },
|
|
ResponseMimeType = "application/json",
|
|
ResponseSchema = schema
|
|
});
|
|
|
|
var successResponse = req.CreateResponse(HttpStatusCode.OK);
|
|
successResponse.Headers.Add("Content-Type", "application/json");
|
|
await successResponse.WriteStringAsync(response.Text!);
|
|
return successResponse;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to generate analysis via Gemini API.");
|
|
var errorResponse = req.CreateResponse(HttpStatusCode.InternalServerError);
|
|
await errorResponse.WriteStringAsync("Error communicating with Gemini API.");
|
|
return errorResponse;
|
|
}
|
|
}
|
|
}
|
|
}
|