dbeaver/pro#8655 refactor action function processing

This commit is contained in:
Dmitrii
2026-04-03 10:01:17 +02:00
parent 5c9d7e6320
commit 47d921ad55
6 changed files with 104 additions and 35 deletions
@@ -48,8 +48,10 @@
class="io.cloudbeaver.websocket.event.client.WSSessionTaskWithParametersConfirmationEvent"/>
<clientEvent id="cb_client_cancel_action"
class="io.cloudbeaver.websocket.event.client.WSSessionCancelActionClientEvent"/>
<clientEvent id="cb_client_ai_function_call_confirmation"
class="io.cloudbeaver.websocket.event.client.WSAiFunctionCallConfirmationClientEvent"/>
<clientEvent id="cb_client_action_confirmation"
class="io.cloudbeaver.websocket.event.client.WSActionConfirmationClientEvent"/>
<clientEvent id="cb_client_action_result"
class="io.cloudbeaver.websocket.event.client.WSActionResultClientEvent"/>
</extension>
</plugin>
@@ -1071,12 +1071,12 @@ public class WebSession extends BaseWebSession
removeAttribute(actionId);
}
public void handleAiFunctionConfirmation(@NotNull String taskId, boolean confirmed) {
public void handleActionConfirmation(@NotNull String actionId, boolean confirmed) {
if (confirmed) {
runAsyncTaskJob(taskId);
runAsyncTaskJob(actionId);
} else {
try {
asyncTaskCancel(taskId);
asyncTaskCancel(actionId);
} catch (DBWebException e) {
log.error("Error cancelling function confirmation task", e);
addSessionError(e);
@@ -1084,6 +1084,16 @@ public class WebSession extends BaseWebSession
}
}
public void handleActionResult(@NotNull String actionId, @NotNull Object result) {
CompletableFuture<Object> future = getAttribute(actionId);
if (future != null) {
future.complete(result);
removeAttribute(actionId);
} else {
log.error("Received unexpected action result event for actionId: " + actionId);
}
}
@NotNull
private String getTaskConfirmationAttributeName(@NotNull String taskId) {
return WebSQLConstants.TASK_CONFIRMATION_ATTR_PREFIX + taskId;
@@ -20,44 +20,26 @@ import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.model.websocket.WSConstants;
import org.jkiss.dbeaver.model.websocket.event.WSClientEvent;
public class WSAiFunctionCallConfirmationClientEvent extends WSClientEvent {
public class WSActionConfirmationClientEvent extends WSClientEvent {
public static final String ID = "cb_client_ai_function_call_confirmation";
public static final String ID = "cb_client_action_confirmation";
@NotNull
private final String conversationId;
@NotNull
private final String messageId;
@NotNull
private final String taskId;
private final String actionId;
private final boolean confirmed;
public WSAiFunctionCallConfirmationClientEvent(
@NotNull String conversationId,
@NotNull String messageId,
@NotNull String taskId,
public WSActionConfirmationClientEvent(
@NotNull String actionId,
boolean confirmed
) {
super(ID, WSConstants.TOPIC_AI);
this.conversationId = conversationId;
this.messageId = messageId;
this.taskId = taskId;
super(ID, WSConstants.TOPIC_SESSION_ACTION);
this.actionId = actionId;
this.confirmed = confirmed;
}
@NotNull
public String getConversationId() {
return conversationId;
}
@NotNull
public String getMessageId() {
return messageId;
}
@NotNull
public String getTaskId() {
return taskId;
public String getActionId() {
return actionId;
}
public boolean isConfirmed() {
@@ -0,0 +1,50 @@
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.cloudbeaver.websocket.event.client;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.model.websocket.WSConstants;
import org.jkiss.dbeaver.model.websocket.event.WSClientEvent;
public class WSActionResultClientEvent extends WSClientEvent {
public static final String ID = "cb_client_action_result";
@NotNull
private final String actionId;
@NotNull
private final Object result;
public WSActionResultClientEvent(
@NotNull String actionId,
@NotNull Object result
) {
super(ID, WSConstants.TOPIC_SESSION_ACTION);
this.actionId = actionId;
this.result = result;
}
@NotNull
public String getActionId() {
return actionId;
}
@NotNull
public Object getResult() {
return result;
}
}
@@ -40,6 +40,8 @@ enum CBClientEventId {
cb_client_projects_active,
cb_client_session_ping,
cb_client_cancel_action @since(version: "26.0.2")
cb_client_action_confirmation @since(version: "26.0.3")
cb_client_action_result @since(version: "26.0.3")
}
"Client subscribes on topic to receive only related events"
@@ -144,6 +146,22 @@ type CBActionCancelledEvent implements CBClientEvent @since(version: "26.0.2") {
actionId: String!
}
"User's action result"
type CBActionResultEvent implements CBClientEvent @since(version: "26.0.3") {
id: CBClientEventId!
topicId: CBEventTopic
actionId: String!
result: Object!
}
"User's action confirmation"
type CBActionConfirmationEvent implements CBClientEvent @since(version: "26.0.3") {
id: CBClientEventId!
topicId: CBEventTopic
actionId: String!
confirmed: Boolean
}
"Async task info status event"
type WSAsyncTaskInfo @since(version: "24.3.1") {
id: CBServerEventId!
@@ -98,10 +98,17 @@ public class CBClientEventProcessor {
}
break;
}
case WSAiFunctionCallConfirmationClientEvent.ID: {
case WSActionConfirmationClientEvent.ID: {
if (webSession instanceof WebSession session) {
var event = (WSAiFunctionCallConfirmationClientEvent) clientEvent;
session.handleAiFunctionConfirmation(event.getTaskId(), event.isConfirmed());
var event = (WSActionConfirmationClientEvent) clientEvent;
session.handleActionConfirmation(event.getActionId(), event.isConfirmed());
}
break;
}
case WSActionResultClientEvent.ID: {
if (webSession instanceof WebSession session) {
var event = (WSActionResultClientEvent) clientEvent;
session.handleActionResult(event.getActionId(), event.getResult());
}
break;
}