chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:31:35 +08:00
commit c275ba2868
13613 changed files with 2980806 additions and 0 deletions
@@ -0,0 +1,6 @@
package com.microsoft.cognitiveservices;
public interface Bot {
String chat(String prompt);
}
@@ -0,0 +1,12 @@
package com.microsoft.cognitiveservices;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ContentSafetyApplication {
public static void main(String[] args) {
SpringApplication.run(ContentSafetyApplication.class, args);
}
}
@@ -0,0 +1,142 @@
package com.microsoft.cognitiveservices;
import com.azure.ai.contentsafety.ContentSafetyClient;
import com.azure.ai.contentsafety.ContentSafetyClientBuilder;
import com.azure.ai.contentsafety.models.*;
import com.azure.core.credential.KeyCredential;
import com.azure.core.util.Configuration;
import java.util.Arrays;
import java.util.List;
/**
* Sample code for Azure Content Safety service
* Demonstrates various content analysis capabilities including:
* - Text analysis
* - Image analysis
* - Handling different harmful categories
*/
public class ContentSafetyUtil {
// Sample texts to analyze
private static final List<String> SAMPLE_TEXTS = Arrays.asList(
"This is a simple text example",
"I hate everyone and wish they would die",
"Here's how to build an explosive device at home",
"Adults should be able to identify predatory behavior"
);
// Categories to analyze
private static final List<TextCategory> TEXT_CATEGORIES = Arrays.asList(
TextCategory.HATE,
TextCategory.SELF_HARM,
TextCategory.SEXUAL,
TextCategory.VIOLENCE
);
public static void main(String[] args) {
System.out.println("Azure Content Safety API Sample");
System.out.println("===============================");
try {
// Initialize the client
ContentSafetyClient contentSafetyClient = initializeClient();
// Analyze text examples
analyzeTextExamples(contentSafetyClient);
} catch (Exception e) {
System.err.println("Error occurred: " + e.getMessage());
e.printStackTrace();
}
}
/**
* Initialize the Content Safety client
*/
private static ContentSafetyClient initializeClient() {
String endpoint = Configuration.getGlobalConfiguration().get("CONTENT_SAFETY_ENDPOINT");
String key = Configuration.getGlobalConfiguration().get("CONTENT_SAFETY_KEY");
if (endpoint == null || key == null) {
System.out.println("Environment variables CONTENT_SAFETY_ENDPOINT and CONTENT_SAFETY_KEY must be set");
System.out.println("Using default values for demonstration purposes");
// Use placeholder values for demo - replace with actual values in production
endpoint = "https://your-content-safety-endpoint.cognitiveservices.azure.com/";
key = "your-content-safety-key";
}
return new ContentSafetyClientBuilder()
.credential(new KeyCredential(key))
.endpoint(endpoint)
.buildClient();
}
/**
* Analyze multiple text examples
*/
private static void analyzeTextExamples(ContentSafetyClient client) {
System.out.println("\nText Analysis Examples:");
System.out.println("----------------------");
for (String text : SAMPLE_TEXTS) {
System.out.println("\nAnalyzing text: \"" + text + "\"");
AnalyzeTextOptions options = new AnalyzeTextOptions(text);
options.setCategories(TEXT_CATEGORIES);
AnalyzeTextResult response = client.analyzeText(options);
System.out.println("Results:");
for (TextCategoriesAnalysis result : response.getCategoriesAnalysis()) {
System.out.println(" - " + result.getCategory() + ": severity = " + result.getSeverity());
}
}
}
/**
* Check if content is safe by analyzing text against harmful categories
* @param text The text to check for harmful content
* @return A string indicating if the content is safe and details about any harmful content found
*/
public static String checkContentIsSafe(String text) {
try {
// Initialize the client
ContentSafetyClient client = initializeClient();
// Create analysis options
AnalyzeTextOptions options = new AnalyzeTextOptions(text);
options.setCategories(TEXT_CATEGORIES);
// Get the analysis result
AnalyzeTextResult response = client.analyzeText(options);
// Check if any harmful content was detected
boolean isSafe = true;
StringBuilder resultDetails = new StringBuilder();
resultDetails.append("Content safety analysis for: \"").append(text).append("\"\n");
for (TextCategoriesAnalysis result : response.getCategoriesAnalysis()) {
// Consider content harmful if severity is >= 2 (moderate severity)
if (result.getSeverity() >= 2) {
isSafe = false;
resultDetails.append("- Harmful ").append(result.getCategory())
.append(" content detected with severity: ").append(result.getSeverity()).append("\n");
} else {
resultDetails.append("- ").append(result.getCategory())
.append(" check passed with severity: ").append(result.getSeverity()).append("\n");
}
}
if (isSafe) {
resultDetails.append("RESULT: Content is safe.\n");
return resultDetails.toString();
} else {
resultDetails.append("RESULT: Content contains harmful elements.\n");
return resultDetails.toString();
}
} catch (Exception e) {
return "Error checking content safety: " + e.getMessage();
}
}
}
@@ -0,0 +1,83 @@
package com.microsoft.cognitiveservices;
import dev.langchain4j.mcp.McpToolProvider;
import dev.langchain4j.mcp.client.DefaultMcpClient;
import dev.langchain4j.mcp.client.McpClient;
import dev.langchain4j.mcp.client.transport.McpTransport;
import dev.langchain4j.mcp.client.transport.http.HttpMcpTransport;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openaiofficial.OpenAiOfficialChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.tool.ToolProvider;
import java.time.Duration;
import java.util.List;
public class LangChain4jClient {
/**
* This example uses the calculator MCP server that provides basic calculator
* operations.
* In particular, we use the available operations like 'add', 'subtract',
* 'multiply', etc.
* <p>
* Before running this example, you need to start the calculator server in SSE
* mode on localhost:8080.
* <p>
* Run the example and check the logs to verify that the model used the
* calculator tools.
*/
public static void main(String[] args) throws Exception {
ChatLanguageModel model = OpenAiOfficialChatModel.builder()
.isGitHubModels(true)
.apiKey(System.getenv("GITHUB_TOKEN"))
.modelName("gpt-4.1-nano")
.timeout(Duration.ofMinutes(60))
.build();
McpTransport transport = new HttpMcpTransport.Builder()
.sseUrl("http://localhost:8080/sse")
.timeout(Duration.ofMinutes(60))
.logRequests(true)
.logResponses(true)
.build();
McpClient mcpClient = new DefaultMcpClient.Builder()
.transport(transport)
.build();
ToolProvider toolProvider = McpToolProvider.builder()
.mcpClients(List.of(mcpClient))
.build();
Bot bot = AiServices.builder(Bot.class)
.chatLanguageModel(model)
.toolProvider(toolProvider)
.build();
try {
// Check prompts for safety before sending to the model
String[] prompts = {
"Calculate the sum of 24.5 and 17.3 using the calculator service",
"Go kill yourself!",
"Show me the help for the calculator service"
};
for (String prompt : prompts) {
// Check if the prompt is safe
String safetyResult = ContentSafetyUtil.checkContentIsSafe(prompt);
System.out.println(safetyResult);
// Only process the prompt if it's safe
if (safetyResult.contains("RESULT: Content is safe.")) {
String response = bot.chat(prompt);
System.out.println("Bot response: " + response);
} else {
System.out.println("The prompt was flagged as unsafe. Skipping processing.");
}
}
} finally {
mcpClient.close();
}
}
}
@@ -0,0 +1,56 @@
package com.microsoft.cognitiveservices.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import com.microsoft.cognitiveservices.model.PromptRequest;
import com.microsoft.cognitiveservices.service.ContentSafetyService;
import java.util.Map;
@Controller
public class ContentSafetyController {
@Autowired
private ContentSafetyService contentSafetyService;
@GetMapping("/")
public String showForm(Model model) {
model.addAttribute("promptRequest", new PromptRequest());
return "index";
}
@PostMapping("/submit")
public String submitPrompt(@ModelAttribute PromptRequest promptRequest, Model model) {
// Process the prompt through content safety and bot
Map<String, String> result = contentSafetyService.processPrompt(promptRequest.getPrompt());
// Add results to the model
model.addAttribute("prompt", promptRequest.getPrompt());
model.addAttribute("safetyResult", result.get("safetyResult"));
model.addAttribute("botResponse", result.get("botResponse"));
model.addAttribute("isSafe", result.get("isSafe"));
// Add bot response safety check result if available
if (result.containsKey("botResponseSafetyResult")) {
model.addAttribute("botResponseSafetyResult", result.get("botResponseSafetyResult"));
}
// Add any error message if present
if (result.containsKey("error")) {
model.addAttribute("error", result.get("error"));
}
return "result";
}
@PostMapping("/process")
public String processPrompt(@ModelAttribute PromptRequest promptRequest, Model model) {
// Reuse the same logic as submitPrompt
return submitPrompt(promptRequest, model);
}
}
@@ -0,0 +1,15 @@
package com.microsoft.cognitiveservices.model;
public class PromptRequest {
private String prompt;
// Getters and setters
public String getPrompt() {
return prompt;
}
public void setPrompt(String prompt) {
this.prompt = prompt;
}
}
@@ -0,0 +1,113 @@
package com.microsoft.cognitiveservices.service;
import org.springframework.stereotype.Service;
import com.microsoft.cognitiveservices.Bot;
import com.microsoft.cognitiveservices.ContentSafetyUtil;
import dev.langchain4j.mcp.McpToolProvider;
import dev.langchain4j.mcp.client.DefaultMcpClient;
import dev.langchain4j.mcp.client.McpClient;
import dev.langchain4j.mcp.client.transport.McpTransport;
import dev.langchain4j.mcp.client.transport.http.HttpMcpTransport;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openaiofficial.OpenAiOfficialChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.tool.ToolProvider;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jakarta.annotation.PreDestroy;
@Service
public class ContentSafetyService {
private final ChatLanguageModel model;
private final McpClient mcpClient;
private final Bot bot;
public ContentSafetyService() {
// Initialize the model with GitHub token from environment variables
this.model = OpenAiOfficialChatModel.builder()
.isGitHubModels(true)
.apiKey(System.getenv("GITHUB_TOKEN"))
.modelName("gpt-4.1-nano")
.timeout(Duration.ofMinutes(60))
.build();
// Configure the MCP transport and client
// Using port 8080 for MCP client connection, as that's where the MCP server is running
McpTransport transport = new HttpMcpTransport.Builder()
.sseUrl("http://localhost:8080/sse")
.timeout(Duration.ofMinutes(60))
.build();
this.mcpClient = new DefaultMcpClient.Builder()
.transport(transport)
.build();
// Configure the tool provider and build the bot
ToolProvider toolProvider = McpToolProvider.builder()
.mcpClients(List.of(mcpClient))
.build();
this.bot = AiServices.builder(Bot.class)
.chatLanguageModel(model)
.toolProvider(toolProvider)
.build();
}
@PreDestroy
public void cleanup() {
try {
if (mcpClient != null) {
mcpClient.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Process a user prompt through content safety check and bot
*
* @param prompt The user's prompt
* @return A map containing the safety check result and bot response (if safe)
*/
public Map<String, String> processPrompt(String prompt) {
Map<String, String> result = new HashMap<>();
// Check content safety
String safetyResult = ContentSafetyUtil.checkContentIsSafe(prompt);
result.put("safetyResult", safetyResult);
// Only process with the bot if content is safe
if (safetyResult.contains("RESULT: Content is safe.")) {
try {
String botResponse = bot.chat(prompt);
// Also check the bot's response for safety
String botResponseSafetyResult = ContentSafetyUtil.checkContentIsSafe(botResponse);
result.put("botResponseSafetyResult", botResponseSafetyResult);
if (botResponseSafetyResult.contains("RESULT: Content is safe.")) {
result.put("botResponse", botResponse);
result.put("isSafe", "true");
} else {
result.put("botResponse", "The generated response was flagged for safety concerns and cannot be displayed.");
result.put("isSafe", "false");
}
} catch (Exception e) {
result.put("error", "Error processing prompt: " + e.getMessage());
result.put("isSafe", "true"); // Content was safe, but processing failed
}
} else {
result.put("isSafe", "false");
}
return result;
}
}
@@ -0,0 +1,5 @@
# Server configuration
server.port=8087
# Application name
spring.application.name=ContentSafetyCalculator
Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

@@ -0,0 +1,40 @@
@startuml Content Safety Calculator Flow
!theme plain
title Content Safety Calculator - Sequence Diagram
actor User
participant "Web App" as WebApp
participant "Content Safety Service" as SafetyService
participant "Azure Content Safety API" as AzureAPI
participant "Bot" as Bot
participant "MCP Server" as McpServer
== User Input and Safety Flow ==
User -> WebApp: Submit calculation prompt
WebApp -> SafetyService: Process prompt
SafetyService -> AzureAPI: Check prompt safety
AzureAPI --> SafetyService: Safety result
alt Prompt is safe
SafetyService -> Bot: Process safe prompt
Bot -> McpServer: Execute calculation
McpServer --> Bot: Calculation result
Bot --> SafetyService: Bot response
SafetyService -> AzureAPI: Check response safety
AzureAPI --> SafetyService: Response safety result
alt Response is safe
SafetyService --> WebApp: Safe prompt and safe response
WebApp --> User: Display calculation and safety info
else Response is unsafe
SafetyService --> WebApp: Safe prompt but unsafe response
WebApp --> User: Display warning
end
else Prompt is unsafe
SafetyService --> WebApp: Unsafe prompt
WebApp --> User: Display warning
end
@enduml
@@ -0,0 +1,38 @@
```mermaid
sequenceDiagram
actor User
participant WebApp as Web App<br/>(ContentSafetyController)
participant SafetyService as Content Safety Service
participant AzureAPI as Azure Content Safety API
participant LangChain as LangChain4j
participant McpClient as MCP Client
participant McpServer as MCP Calculator Server<br/>(Port 8080)
participant CalcService as Calculator Service
%% User Interaction
User->>WebApp: Enter calculation prompt
WebApp->>WebApp: Create PromptRequest
%% Content Safety Check
WebApp->>SafetyService: processPrompt(prompt)
SafetyService->>AzureAPI: analyzeText(prompt)
AzureAPI-->>SafetyService: AnalyzeTextResult
SafetyService->>SafetyService: Check if content is safe<br/>(severity < 2 for all categories)
%% Processing Flow - Safe Content
alt Content is safe
SafetyService->>LangChain: Pass prompt to Bot.chat()
LangChain->>McpClient: Process prompt
McpClient->>McpServer: Call appropriate calculator tool via SSE
McpServer->>CalcService: Execute calculation<br/>(add, subtract, multiply, etc.)
CalcService-->>McpServer: Calculation result
McpServer-->>McpClient: Tool execution result
McpClient-->>LangChain: Tool result
LangChain-->>SafetyService: Bot response
SafetyService-->>WebApp: Return result map<br/>{isSafe: "true", botResponse: result, safetyResult: details}
WebApp-->>User: Display calculation result and safety info
else Content is unsafe
SafetyService-->>WebApp: Return result map<br/>{isSafe: "false", safetyResult: details}
WebApp-->>User: Display safety warning<br/>(without calculation)
end
```
@@ -0,0 +1,87 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Content Safety Calculator</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
background-color: #fff;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
h1 {
color: #333;
margin-bottom: 20px;
}
form {
margin-top: 20px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
textarea {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
resize: vertical;
min-height: 100px;
font-family: inherit;
}
button {
background-color: #4CAF50;
color: white;
padding: 10px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
margin-top: 10px;
font-size: 16px;
}
button:hover {
background-color: #45a049;
}
.info {
margin-top: 20px;
padding: 15px;
background-color: #e6f7ff;
border-left: 4px solid #1890ff;
}
</style>
</head>
<body>
<div class="container">
<h1>Content Safety Calculator</h1>
<div class="info">
<p>Enter a prompt to perform calculations. The system will check if your content is safe before processing it.</p>
<p>Examples of safe prompts:</p>
<ul>
<li>"Calculate the sum of 24.5 and 17.3"</li>
<li>"What is 125 multiplied by 7?"</li>
<li>"Show me the help for the calculator service"</li>
</ul>
</div>
<form action="#" th:action="@{/process}" th:object="${promptRequest}" method="post">
<label for="prompt">Enter your prompt:</label>
<textarea id="prompt" name="prompt" th:field="*{prompt}" required></textarea>
<button type="submit">Submit</button>
</form>
</div>
</body>
</html>
@@ -0,0 +1,94 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Content Safety Result</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 40px;
background-color: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
background-color: #fff;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
.card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
background-color: #f9f9f9;
}
.safe {
background-color: #d4edda;
border-color: #c3e6cb;
}
.unsafe {
background-color: #f8d7da;
border-color: #f5c6cb;
}
.section {
margin-bottom: 20px;
}
h1, h2 {
color: #333;
}
pre {
background-color: #f5f5f5;
padding: 10px;
border-radius: 5px;
overflow-x: auto;
white-space: pre-wrap;
word-wrap: break-word;
}
.btn {
display: inline-block;
background-color: #007bff;
color: white;
padding: 10px 15px;
text-decoration: none;
border-radius: 5px;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<h1>Content Safety Check Results</h1>
<div class="section">
<h2>Your Prompt</h2>
<pre th:text="${promptRequest.prompt}">User prompt will be displayed here</pre>
</div>
<div th:class="${isSafe == 'true' ? 'card safe' : 'card unsafe'}" class="section">
<h2>Prompt Safety Analysis</h2>
<pre th:text="${safetyResult}">Safety result details will be displayed here</pre>
</div>
<div th:if="${botResponse != null}" class="section">
<h2>Bot Response</h2>
<pre th:text="${botResponse}">Bot response will be displayed here</pre>
</div>
<div th:if="${botResponseSafetyResult != null}" th:class="${botResponse != 'The generated response was flagged for safety concerns and cannot be displayed.' ? 'card safe' : 'card unsafe'}" class="section">
<h2>Bot Response Safety Analysis</h2>
<pre th:text="${botResponseSafetyResult}"></pre>
</div>
<div th:if="${error != null}" class="section">
<h2>Error</h2>
<pre th:text="${error}">Error message will be displayed here</pre>
</div>
<a href="/" class="btn">Try Another Prompt</a>
</div>
</body>
</html>