Skip to content

Commit 42fbb3e

Browse files
Copilotphrocker
andcommitted
Implement ATPL chat configuration system with enhanced capabilities model
Co-authored-by: phrocker <[email protected]>
1 parent 65c8bee commit 42fbb3e

File tree

6 files changed

+1043
-1
lines changed

6 files changed

+1043
-1
lines changed
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
package io.sentrius.sso.controllers.api;
2+
3+
import java.util.HashMap;
4+
import java.util.List;
5+
import java.util.Map;
6+
import com.fasterxml.jackson.databind.JsonNode;
7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
import com.fasterxml.jackson.databind.node.ArrayNode;
9+
import com.fasterxml.jackson.databind.node.ObjectNode;
10+
import io.sentrius.sso.core.annotations.LimitAccess;
11+
import io.sentrius.sso.core.config.SystemOptions;
12+
import io.sentrius.sso.core.controllers.BaseController;
13+
import io.sentrius.sso.core.model.security.enums.ApplicationAccessEnum;
14+
import io.sentrius.sso.core.services.ATPLPolicyService;
15+
import io.sentrius.sso.core.services.ErrorOutputService;
16+
import io.sentrius.sso.core.services.UserService;
17+
import io.sentrius.sso.core.trust.ATPLPolicy;
18+
import io.sentrius.sso.services.ATPLChatService;
19+
import jakarta.servlet.http.HttpServletRequest;
20+
import jakarta.servlet.http.HttpServletResponse;
21+
import lombok.extern.slf4j.Slf4j;
22+
import org.springframework.http.ResponseEntity;
23+
import org.springframework.web.bind.annotation.*;
24+
25+
@Slf4j
26+
@RestController
27+
@RequestMapping("/api/v1/atpl/chat")
28+
public class ATPLChatController extends BaseController {
29+
30+
private final ATPLChatService atplChatService;
31+
private final ATPLPolicyService atplPolicyService;
32+
private final ObjectMapper objectMapper;
33+
34+
// Store conversation sessions (in production, use Redis or database)
35+
private final Map<String, Map<String, Object>> chatSessions = new HashMap<>();
36+
37+
public ATPLChatController(
38+
UserService userService,
39+
SystemOptions systemOptions,
40+
ErrorOutputService errorOutputService,
41+
ATPLChatService atplChatService,
42+
ATPLPolicyService atplPolicyService,
43+
ObjectMapper objectMapper
44+
) {
45+
super(userService, systemOptions, errorOutputService);
46+
this.atplChatService = atplChatService;
47+
this.atplPolicyService = atplPolicyService;
48+
this.objectMapper = objectMapper;
49+
}
50+
51+
@PostMapping("/message")
52+
@LimitAccess(applicationAccess = {ApplicationAccessEnum.CAN_MANAGE_APPLICATION})
53+
public ResponseEntity<ObjectNode> processMessage(
54+
@RequestBody Map<String, Object> request,
55+
HttpServletRequest httpRequest,
56+
HttpServletResponse httpResponse
57+
) {
58+
try {
59+
String sessionId = (String) request.get("sessionId");
60+
String message = (String) request.get("message");
61+
62+
if (sessionId == null || message == null) {
63+
return ResponseEntity.badRequest().body(createErrorResponse("Session ID and message are required"));
64+
}
65+
66+
// Get or create session context
67+
Map<String, Object> sessionContext = chatSessions.computeIfAbsent(sessionId, k -> new HashMap<>());
68+
69+
// Process the message with the ATPL chat service
70+
String response = atplChatService.processATPLChatMessage(message, sessionContext);
71+
72+
// Update session context with conversation history
73+
updateSessionContext(sessionContext, message, response);
74+
75+
ObjectNode result = objectMapper.createObjectNode();
76+
result.put("response", response);
77+
result.put("sessionId", sessionId);
78+
79+
return ResponseEntity.ok(result);
80+
81+
} catch (Exception e) {
82+
log.error("Error processing ATPL chat message: {}", e.getMessage(), e);
83+
return ResponseEntity.internalServerError().body(createErrorResponse("Failed to process message"));
84+
}
85+
}
86+
87+
@PostMapping("/generate-policy")
88+
@LimitAccess(applicationAccess = {ApplicationAccessEnum.CAN_MANAGE_APPLICATION})
89+
public ResponseEntity<ObjectNode> generatePolicy(
90+
@RequestBody Map<String, Object> request,
91+
HttpServletRequest httpRequest,
92+
HttpServletResponse httpResponse
93+
) {
94+
try {
95+
String sessionId = (String) request.get("sessionId");
96+
Map<String, Object> sessionContext = chatSessions.get(sessionId);
97+
98+
if (sessionContext == null) {
99+
return ResponseEntity.badRequest().body(createErrorResponse("Session not found"));
100+
}
101+
102+
ObjectNode policyNode = atplChatService.generateATPLPolicy(sessionContext);
103+
104+
ObjectNode result = objectMapper.createObjectNode();
105+
result.set("policy", policyNode);
106+
result.put("sessionId", sessionId);
107+
108+
return ResponseEntity.ok(result);
109+
110+
} catch (Exception e) {
111+
log.error("Error generating ATPL policy: {}", e.getMessage(), e);
112+
return ResponseEntity.internalServerError().body(createErrorResponse("Failed to generate policy"));
113+
}
114+
}
115+
116+
@GetMapping("/suggestions")
117+
@LimitAccess(applicationAccess = {ApplicationAccessEnum.CAN_MANAGE_APPLICATION})
118+
public ResponseEntity<ObjectNode> getSuggestions(
119+
@RequestParam String description,
120+
HttpServletRequest httpRequest,
121+
HttpServletResponse httpResponse
122+
) {
123+
try {
124+
List<String> suggestions = atplChatService.suggestCapabilities(description);
125+
126+
ObjectNode result = objectMapper.createObjectNode();
127+
ArrayNode suggestionsArray = objectMapper.createArrayNode();
128+
suggestions.forEach(suggestionsArray::add);
129+
result.set("suggestions", suggestionsArray);
130+
131+
return ResponseEntity.ok(result);
132+
133+
} catch (Exception e) {
134+
log.error("Error getting suggestions: {}", e.getMessage(), e);
135+
return ResponseEntity.internalServerError().body(createErrorResponse("Failed to get suggestions"));
136+
}
137+
}
138+
139+
@GetMapping("/existing-policies")
140+
@LimitAccess(applicationAccess = {ApplicationAccessEnum.CAN_MANAGE_APPLICATION})
141+
public ResponseEntity<ObjectNode> getExistingPolicies(
142+
HttpServletRequest httpRequest,
143+
HttpServletResponse httpResponse
144+
) {
145+
try {
146+
List<ATPLPolicy> policies = atplPolicyService.getAllPolicies();
147+
148+
ObjectNode result = objectMapper.createObjectNode();
149+
ArrayNode policiesArray = objectMapper.createArrayNode();
150+
151+
for (ATPLPolicy policy : policies) {
152+
ObjectNode policyNode = objectMapper.createObjectNode();
153+
policyNode.put("id", policy.getPolicyId());
154+
policyNode.put("description", policy.getDescription());
155+
policyNode.put("version", policy.getVersion());
156+
157+
if (policy.getCapabilities() != null && policy.getCapabilities().getPrimitives() != null) {
158+
ArrayNode capabilitiesArray = objectMapper.createArrayNode();
159+
policy.getCapabilities().getPrimitives().forEach(cap -> {
160+
ObjectNode capNode = objectMapper.createObjectNode();
161+
capNode.put("id", cap.getId());
162+
capNode.put("description", cap.getDescription());
163+
capabilitiesArray.add(capNode);
164+
});
165+
policyNode.set("capabilities", capabilitiesArray);
166+
}
167+
168+
policiesArray.add(policyNode);
169+
}
170+
171+
result.set("policies", policiesArray);
172+
return ResponseEntity.ok(result);
173+
174+
} catch (Exception e) {
175+
log.error("Error getting existing policies: {}", e.getMessage(), e);
176+
return ResponseEntity.internalServerError().body(createErrorResponse("Failed to get existing policies"));
177+
}
178+
}
179+
180+
private void updateSessionContext(Map<String, Object> sessionContext, String userMessage, String agentResponse) {
181+
// Store conversation history
182+
@SuppressWarnings("unchecked")
183+
List<Map<String, String>> history = (List<Map<String, String>>) sessionContext.computeIfAbsent("conversation_history", k -> new java.util.ArrayList<>());
184+
185+
Map<String, String> userEntry = new HashMap<>();
186+
userEntry.put("type", "user");
187+
userEntry.put("message", userMessage);
188+
history.add(userEntry);
189+
190+
Map<String, String> agentEntry = new HashMap<>();
191+
agentEntry.put("type", "assistant");
192+
agentEntry.put("message", agentResponse);
193+
history.add(agentEntry);
194+
195+
// Keep only last 10 exchanges
196+
if (history.size() > 20) {
197+
history.subList(0, history.size() - 20).clear();
198+
}
199+
}
200+
201+
private ObjectNode createErrorResponse(String message) {
202+
ObjectNode error = objectMapper.createObjectNode();
203+
error.put("error", message);
204+
return error;
205+
}
206+
}

api/src/main/java/io/sentrius/sso/controllers/view/ATPLConfigController.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,10 @@ public String configurePage(Model model, @RequestParam(name= "id", required=fals
6464
}
6565
return "sso/atpl/configure";
6666
}
67+
68+
@GetMapping("/chat")
69+
@LimitAccess(applicationAccess = {ApplicationAccessEnum.CAN_MANAGE_APPLICATION})
70+
public String chatPage(Model model) {
71+
return "sso/atpl/chat";
72+
}
6773
}

0 commit comments

Comments
 (0)