Skip to content

Commit 4c068ca

Browse files
committed
Fix tooltip service
1 parent deb8e23 commit 4c068ca

File tree

7 files changed

+99
-28
lines changed

7 files changed

+99
-28
lines changed

.azure.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
SENTRIUS_VERSION=1.1.120
1+
SENTRIUS_VERSION=1.1.140
22
SENTRIUS_SSH_VERSION=1.1.12
33
SENTRIUS_KEYCLOAK_VERSION=1.1.15
44
SENTRIUS_AGENT_VERSION=1.1.24

api/src/main/java/io/sentrius/sso/controllers/api/HostApiController.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ public ResponseEntity<Map<String, Object>> initiateRdpSession(
353353
sessionData.put("jwtToken", jwtToken);
354354
sessionData.put("target", hostSystem.getId());
355355
sessionData.put("websocketHost", systemOptions.getRdpProxyDomain());
356+
sessionData.put("websocketBaseUrl", "/guacamole/tunnel");
356357
sessionData.put("websocketUrl", "/guacamole/tunnel?token=" + jwtToken);
357358
sessionData.put("displayName", hostSystem.getDisplayName());
358359

api/src/main/java/io/sentrius/sso/controllers/api/TooltipController.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import java.util.HashMap;
2828
import java.util.Map;
29+
import java.util.UUID;
2930

3031
/**
3132
* REST Controller for AI-powered tooltip and contextual help features.
@@ -82,7 +83,7 @@ public ResponseEntity<TooltipDescribeResponse> describe(
8283
}
8384

8485
// Build token DTO for LLM service
85-
TokenDTO tokenDTO = TokenDTO.builder().build();
86+
TokenDTO tokenDTO = TokenDTO.builder().communicationId(UUID.randomUUID().toString()).build();
8687
// Token will be populated from security context by LLM service
8788

8889
// Generate description

api/src/main/resources/static/js/ai-helper.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
* AI Helper Library
33
* Enables right-click context menu to get AI-powered descriptions and chat assistance
44
*/
5-
<script th:inline="javascript">
6-
var csrf = [[${session._csrf}]];
7-
</script>
85

96
(function(window, document) {
107
'use strict';

api/src/main/resources/templates/fragments/header.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,16 @@
439439
});
440440

441441
/*]]>*/
442+
443+
// Initialize AI Helper after DOM is fully loaded
444+
document.addEventListener('DOMContentLoaded', function() {
445+
const aiHelper = new AIHelper({
446+
apiEndpoint: '/api/v1/tooltip'
447+
});
448+
console.log('AI Helper initialized with mock API');
449+
});
442450
</script>
443451

444452

453+
445454
</head>

api/src/main/resources/templates/sso/enclaves/list_servers.html

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -285,17 +285,57 @@ <h5 class="modal-title" id="rdpModalLabel">RDP Session - <span id="rdpHostName">
285285

286286
function initializeRdpConnection(sessionData) {
287287
// Build the WebSocket tunnel to guacd via your proxy
288-
const u = new URL(sessionData.websocketUrl, sessionData.websocketHost);
289-
u.protocol = (u.protocol === 'https:') ? 'wss:' : 'ws:';
290-
const wsUrl = u.toString();
291-
292-
console.log("Connecting to Guacamole WebSocket:", wsUrl);
293-
console.log("Connecting to Guacamole WebSocket:", sessionData.websocketUrl);
294-
console.log("Connecting to Guacamole WebSocket:", sessionData.websocketHost);
288+
// Build the WebSocket URL with the token as a query parameter
289+
const baseUrl = sessionData.websocketHost;
290+
const path = sessionData.websocketBaseUrl;
291+
const token = sessionData.jwtToken;
292+
// Construct the WebSocket URL
293+
const url = new URL(path, baseUrl);
294+
url.protocol = (url.protocol === 'https:') ? 'wss:' : 'ws:';
295+
url.searchParams.set('token', token);
296+
const wsUrlWithToken = url.toString();
297+
298+
console.log("=== RDP Connection Debug Info ===");
299+
console.log("Platform:", navigator.platform);
300+
console.log("User Agent:", navigator.userAgent);
301+
console.log("WebSocket URL:", wsUrlWithToken);
302+
console.log("===============================");
303+
304+
const OriginalWebSocket = window.WebSocket;
305+
const isChromium = /Chrome|Chromium|Edg/.test(navigator.userAgent);
306+
307+
window.WebSocket = function(url, protocols) {
308+
// Clean the URL if it has ?undefined or &undefined
309+
let cleanUrl = url.replace(/[?&]undefined/g, '');
310+
console.log("WebSocket constructor called with:", url);
311+
console.log("Cleaned URL:", cleanUrl);
312+
console.log("Protocols:", protocols);
313+
console.log("Browser is Chromium:", isChromium);
314+
315+
// Chrome/Edge are strict about subprotocol negotiation
316+
// Don't specify subprotocol to avoid rejection
317+
if (isChromium) {
318+
console.log("Chromium browser detected - connecting without subprotocol");
319+
return new OriginalWebSocket(cleanUrl);
320+
} else {
321+
console.log("Non-Chromium browser - connecting with subprotocol:", protocols);
322+
return new OriginalWebSocket(cleanUrl, protocols);
323+
}
324+
};
295325

296-
const tunnel = new Guacamole.WebSocketTunnel(wsUrl);
326+
try {
327+
// Use standard Guacamole WebSocketTunnel
328+
const tunnel = new Guacamole.WebSocketTunnel(wsUrlWithToken);
297329
const client = new Guacamole.Client(tunnel);
298330

331+
tunnel.onerror = function(status) {
332+
console.error("Tunnel error:", status.code, status.message);
333+
const statusDiv = document.getElementById("rdpConnectionStatus");
334+
if (statusDiv) {
335+
statusDiv.className = "alert alert-danger";
336+
statusDiv.innerHTML = `<i class='fa fa-exclamation-triangle'></i> Tunnel Error: ${status.code} - ${status.message || 'Connection failed'}`;
337+
}
338+
};
299339
tunnel.onerror = function(status) {
300340
console.error("Tunnel error:", status.code, status.message);
301341
};
@@ -313,12 +353,13 @@ <h5 class="modal-title" id="rdpModalLabel">RDP Session - <span id="rdpHostName">
313353

314354
// Clear any previous content
315355
displayDiv.innerHTML = '<div id="rdpControls" style="position: absolute; top: 10px; right: 10px; background: rgba(0,0,0,0.7); padding: 5px; border-radius: 3px; z-index: 100;"><button class="btn btn-sm btn-secondary" onclick="disconnectRdp()" title="Disconnect"><i class="fa fa-power-off"></i></button></div>';
316-
356+
317357
// Get the display element and append it
318358
const guacDisplay = client.getDisplay().getElement();
319359
displayDiv.appendChild(guacDisplay);
320360

321361
// Now connect
362+
//client.connect();
322363
client.connect();
323364

324365
$('#rdpModal').on('shown.bs.modal', function () {
@@ -389,6 +430,13 @@ <h5 class="modal-title" id="rdpModalLabel">RDP Session - <span id="rdpHostName">
389430
break;
390431
}
391432
};
433+
434+
} finally {
435+
// Restore original WebSocket after a short delay
436+
setTimeout(() => {
437+
window.WebSocket = OriginalWebSocket;
438+
}, 1000);
439+
}
392440
}
393441

394442

dataplane/src/main/java/io/sentrius/sso/core/services/tooltip/TooltipService.java

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package io.sentrius.sso.core.services.tooltip;
22

33
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.JsonNode;
5+
import io.sentrius.sso.core.config.SystemOptions;
6+
import io.sentrius.sso.core.dto.SystemOption;
47
import io.sentrius.sso.core.dto.documents.DocumentSearchDTO;
58
import io.sentrius.sso.core.dto.tooltip.TooltipChatRequest;
69
import io.sentrius.sso.core.dto.tooltip.TooltipChatResponse;
@@ -33,6 +36,7 @@ public class TooltipService {
3336

3437
private final DocumentService documentService;
3538
private final LLMService llmService;
39+
private final SystemOptions systemOptions;
3640

3741
@Value("${sentrius.tooltip.max-context-documents:5}")
3842
private int maxContextDocuments;
@@ -43,9 +47,10 @@ public class TooltipService {
4347
@Value("${sentrius.tooltip.llm-model:gpt-4o-mini}")
4448
private String llmModel;
4549

46-
public TooltipService(DocumentService documentService, LLMService llmService) {
50+
public TooltipService(DocumentService documentService, LLMService llmService, SystemOptions systemOptions) {
4751
this.documentService = documentService;
4852
this.llmService = llmService;
53+
this.systemOptions = systemOptions;
4954
}
5055

5156
/**
@@ -325,19 +330,29 @@ private String callLLM(String systemContext, String userPrompt, TokenDTO tokenDT
325330
request.put("temperature", 0.7);
326331

327332
// Call LLM
328-
String responseJson = llmService.askQuestion(tokenDTO, request);
329-
330-
// Parse response
331-
var response = JsonUtil.MAPPER.readTree(responseJson);
332-
var choices = response.get("choices");
333-
if (choices != null && choices.isArray() && !choices.isEmpty()) {
334-
var firstChoice = choices.get(0);
335-
var message = firstChoice.get("message");
336-
if (message != null) {
337-
var content = message.get("content");
338-
if (content != null) {
339-
return content.asText();
340-
}
333+
String llmResponse = llmService.askQuestion(tokenDTO,systemOptions.getIntegrationProxyUrl(), request);
334+
335+
336+
// Parse the response
337+
JsonNode responseJson = JsonUtil.MAPPER.readTree(llmResponse);
338+
339+
// Handle both old format (choices) and new format (output)
340+
JsonNode outputNode = responseJson.get("output");
341+
if (outputNode != null && outputNode.isArray() && outputNode.size() > 0) {
342+
// New format: output array
343+
JsonNode messageNode = outputNode.get(0);
344+
JsonNode contentArray = messageNode.get("content");
345+
if (contentArray != null && contentArray.isArray() && contentArray.size() > 0) {
346+
return contentArray.get(0).get("text").asText();
347+
}
348+
} else {
349+
// Old format: choices array
350+
JsonNode choicesNode = responseJson.get("choices");
351+
if (choicesNode != null && choicesNode.isArray() && choicesNode.size() > 0) {
352+
return choicesNode.get(0)
353+
.get("message")
354+
.get("content")
355+
.asText();
341356
}
342357
}
343358

0 commit comments

Comments
 (0)