diff --git a/.gitignore b/.gitignore
index 1aee6e7dd7..f6904bc1da 100644
--- a/.gitignore
+++ b/.gitignore
@@ -387,6 +387,7 @@ log
**/vectorization-api-event-profile.json
**/vectorization-worker-event-profile.json
deploy/quick-start/.env
+deploy/quick-start/tools
**/management-api-event-profile.json
**/testsettings.json
diff --git a/src/dotnet/Common/Models/Orchestration/LongRunningOperation.cs b/src/dotnet/Common/Models/Orchestration/LongRunningOperation.cs
new file mode 100644
index 0000000000..7ac1380e5e
--- /dev/null
+++ b/src/dotnet/Common/Models/Orchestration/LongRunningOperation.cs
@@ -0,0 +1,34 @@
+using System.Text.Json.Serialization;
+
+namespace FoundationaLLM.Common.Models.Orchestration
+{
+ ///
+ /// Represents the current state of a long-running operation.
+ ///
+ public class LongRunningOperation
+ {
+ ///
+ /// The identifier of the long-running operation.
+ ///
+ [JsonPropertyName("operation_id")]
+ public required string OperationId { get; set; }
+
+ ///
+ /// The status of the long-running operation.
+ ///
+ [JsonPropertyName("status")]
+ public required OperationStatus Status { get; set; }
+
+ ///
+ /// The message describing the current state of the operation.
+ ///
+ [JsonPropertyName("status_message")]
+ public string? StatusMessage { get; set; }
+
+ ///
+ /// The time stamp of the last update to the operation.
+ ///
+ [JsonPropertyName("last_updated")]
+ public DateTime? LastUpdated { get; set; }
+ }
+}
diff --git a/src/dotnet/Common/Models/Orchestration/OperationState.cs b/src/dotnet/Common/Models/Orchestration/OperationState.cs
deleted file mode 100644
index 2f07f6b8be..0000000000
--- a/src/dotnet/Common/Models/Orchestration/OperationState.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-namespace FoundationaLLM.Common.Models.Orchestration
-{
- ///
- /// Represents the current state of a long running operation.
- ///
- public class OperationState
- {
- ///
- /// The identifier of the long running operation.
- ///
- public required string OperationId { get; set; }
-
- ///
- /// The status of the long running operation.
- ///
- public required OperationStatus Status { get; set; }
-
- ///
- /// The message describing the current state of the operation.
- ///
- public string? Message { get; set; }
- }
-}
diff --git a/src/dotnet/Core/Interfaces/ICoreService.cs b/src/dotnet/Core/Interfaces/ICoreService.cs
index 54fe8523e6..27cc886576 100644
--- a/src/dotnet/Core/Interfaces/ICoreService.cs
+++ b/src/dotnet/Core/Interfaces/ICoreService.cs
@@ -83,4 +83,28 @@ public interface ICoreService
/// The id of the completion prompt to retrieve.
///
Task GetCompletionPrompt(string instanceId, string sessionId, string completionPromptId);
+
+ ///
+ /// Begins a completion operation.
+ ///
+ /// The FoundationaLLM instance id.
+ /// The completion request containing the user prompt and message history.
+ /// Returns an object containing the OperationId and Status.
+ Task StartCompletionOperation(string instanceId, CompletionRequest completionRequest);
+
+ ///
+ /// Gets the status of a completion operation.
+ ///
+ /// The FoundationaLLM instance id.
+ /// The OperationId for which to retrieve the status.
+ /// Returns an object containing the OperationId and Status.
+ Task GetCompletionOperationStatus(string instanceId, string operationId);
+
+ ///
+ /// Gets a completion operation from the downstream API.
+ ///
+ /// The FoundationaLLM instance id.
+ /// The ID of the operation to retrieve.
+ /// Returns a object.
+ Task GetCompletionOperationResult(string instanceId, string operationId);
}
diff --git a/src/dotnet/Core/Services/CoreService.cs b/src/dotnet/Core/Services/CoreService.cs
index 4269735ca7..89cb8bea9f 100644
--- a/src/dotnet/Core/Services/CoreService.cs
+++ b/src/dotnet/Core/Services/CoreService.cs
@@ -159,6 +159,18 @@ public async Task GetCompletionAsync(string instanceId, CompletionRe
}
}
+ ///
+ public async Task StartCompletionOperation(string instanceId, CompletionRequest completionRequest) =>
+ throw new NotImplementedException();
+
+ ///
+ public Task GetCompletionOperationStatus(string instanceId, string operationId) =>
+ throw new NotImplementedException();
+
+ ///
+ public async Task GetCompletionOperationResult(string instanceId, string operationId) =>
+ throw new NotImplementedException();
+
///
public async Task GenerateChatSessionNameAsync(string instanceId, string? sessionId, string? text)
{
diff --git a/src/dotnet/CoreAPI/Controllers/CompletionsController.cs b/src/dotnet/CoreAPI/Controllers/CompletionsController.cs
index 59adadd71b..dea9f6e876 100644
--- a/src/dotnet/CoreAPI/Controllers/CompletionsController.cs
+++ b/src/dotnet/CoreAPI/Controllers/CompletionsController.cs
@@ -19,7 +19,7 @@ namespace FoundationaLLM.Core.API.Controllers
///
[Authorize(Policy = "DefaultPolicy")]
[ApiController]
- [Route("instances/{instanceId}/[controller]")]
+ [Route("instances/{instanceId}")]
public class CompletionsController : ControllerBase
{
private readonly ICoreService _coreService;
@@ -60,17 +60,50 @@ public CompletionsController(ICoreService coreService,
///
/// The instance ID of the current request.
/// The user prompt for which to generate a completion.
- [HttpPost(Name = "GetCompletion")]
+ [HttpPost("completions", Name = "GetCompletion")]
public async Task GetCompletion(string instanceId, [FromBody] CompletionRequest completionRequest) =>
!string.IsNullOrWhiteSpace(completionRequest.SessionId) ? Ok(await _coreService.GetChatCompletionAsync(instanceId, completionRequest)) :
Ok(await _coreService.GetCompletionAsync(instanceId, completionRequest));
+ ///
+ /// Begins a completion operation.
+ ///
+ /// The FoundationaLLM instance id.
+ /// The completion request containing the user prompt and message history.
+ /// Returns an object containing the OperationId and Status.
+ [HttpPost("async-completions")]
+ public async Task> StartCompletionOperation(string instanceId, CompletionRequest completionRequest)
+ {
+ var state = await _coreService.StartCompletionOperation(instanceId, completionRequest);
+ return Accepted(state);
+ }
+
+ ///
+ /// Gets the status of a completion operation.
+ ///
+ /// The FoundationaLLM instance id.
+ /// The OperationId for which to retrieve the status.
+ /// Returns an object containing the OperationId and Status.
+ [HttpGet("async-completions/{operationId}/status")]
+ public async Task GetCompletionOperationStatus(string instanceId, string operationId) =>
+ await _coreService.GetCompletionOperationStatus(instanceId, operationId);
+
+ ///
+ /// Gets a completion operation from the downstream APIs.
+ ///
+ /// The FoundationaLLM instance id.
+ /// The ID of the operation to retrieve.
+ /// Returns a completion response
+ [HttpGet("async-completions/{operationId}/result")]
+ public async Task GetCompletionOperationResult(string instanceId, string operationId) =>
+ await _coreService.GetCompletionOperationResult(instanceId, operationId);
+
///
/// Retrieves a list of global and private agents.
///
/// The instance ID of the current request.
/// A list of available agents.
- [HttpGet("agents", Name = "GetAgents")]
+ [HttpGet("completions/agents", Name = "GetAgents")]
public async Task>> GetAgents(string instanceId) =>
await _agentResourceProvider.GetResourcesWithRBAC(instanceId, _callContext.CurrentUserIdentity!);
}
diff --git a/src/dotnet/Gatekeeper/Interfaces/IGatekeeperService.cs b/src/dotnet/Gatekeeper/Interfaces/IGatekeeperService.cs
index 7b856c7d21..7a0a0714a4 100644
--- a/src/dotnet/Gatekeeper/Interfaces/IGatekeeperService.cs
+++ b/src/dotnet/Gatekeeper/Interfaces/IGatekeeperService.cs
@@ -20,16 +20,16 @@ public interface IGatekeeperService
///
/// The FoundationaLLM instance id.
/// The completion request containing the user prompt and message history.
- /// Returns an object containing the OperationId and Status.
- Task StartCompletionOperation(string instanceId, CompletionRequest completionRequest);
+ /// Returns an object containing the OperationId and Status.
+ Task StartCompletionOperation(string instanceId, CompletionRequest completionRequest);
///
/// Gets the status of a completion operation.
///
/// The FoundationaLLM instance id.
/// The OperationId to retrieve the status for.
- /// Returns an object containing the OperationId and Status.
- Task GetCompletionOperationStatus(string instanceId, string operationId);
+ /// Returns an object containing the OperationId and Status.
+ Task GetCompletionOperationStatus(string instanceId, string operationId);
///
/// Gets a completion operation from the Gatekeeper service.
@@ -37,5 +37,5 @@ public interface IGatekeeperService
/// The FoundationaLLM instance id.
/// The ID of the operation to retrieve.
/// Returns a object.
- Task GetCompletionOperation(string instanceId, string operationId);
+ Task GetCompletionOperationResult(string instanceId, string operationId);
}
diff --git a/src/dotnet/Gatekeeper/Services/GatekeeperService.cs b/src/dotnet/Gatekeeper/Services/GatekeeperService.cs
index 7db07df40a..185f6ca13d 100644
--- a/src/dotnet/Gatekeeper/Services/GatekeeperService.cs
+++ b/src/dotnet/Gatekeeper/Services/GatekeeperService.cs
@@ -92,15 +92,15 @@ public async Task GetCompletion(string instanceId, Completio
}
///
- public async Task StartCompletionOperation(string instanceId, CompletionRequest completionRequest) =>
+ public async Task StartCompletionOperation(string instanceId, CompletionRequest completionRequest) =>
// TODO: Need to call State API to start the operation.
throw new NotImplementedException();
///
- public Task GetCompletionOperationStatus(string instanceId, string operationId) => throw new NotImplementedException();
+ public Task GetCompletionOperationStatus(string instanceId, string operationId) => throw new NotImplementedException();
///
- public async Task GetCompletionOperation(string instanceId, string operationId) =>
+ public async Task GetCompletionOperationResult(string instanceId, string operationId) =>
// TODO: Need to call State API to get the operation.
throw new NotImplementedException();
diff --git a/src/dotnet/GatekeeperAPI/Controllers/CompletionsController.cs b/src/dotnet/GatekeeperAPI/Controllers/CompletionsController.cs
index a40e3fc003..d1890e5dc3 100644
--- a/src/dotnet/GatekeeperAPI/Controllers/CompletionsController.cs
+++ b/src/dotnet/GatekeeperAPI/Controllers/CompletionsController.cs
@@ -35,9 +35,9 @@ public async Task GetCompletion(string instanceId, Completio
///
/// The FoundationaLLM instance id.
/// The completion request containing the user prompt and message history.
- /// Returns an object containing the OperationId and Status.
+ /// Returns an object containing the OperationId and Status.
[HttpPost("async-completions")]
- public async Task> StartCompletionOperation(string instanceId, CompletionRequest completionRequest)
+ public async Task> StartCompletionOperation(string instanceId, CompletionRequest completionRequest)
{
var state = await _gatekeeperService.StartCompletionOperation(instanceId, completionRequest);
return Accepted(state);
@@ -48,9 +48,9 @@ public async Task> StartCompletionOperation(string
///
/// The FoundationaLLM instance id.
/// The OperationId for which to retrieve the status.
- /// Returns an object containing the OperationId and Status.
+ /// Returns an object containing the OperationId and Status.
[HttpGet("async-completions/{operationId}/status")]
- public async Task GetCompletionOperationStatus(string instanceId, string operationId) =>
+ public async Task GetCompletionOperationStatus(string instanceId, string operationId) =>
await _gatekeeperService.GetCompletionOperationStatus(instanceId, operationId);
///
@@ -60,8 +60,8 @@ public async Task GetCompletionOperationStatus(string instanceId
/// The ID of the operation to retrieve.
/// Returns a completion response
[HttpGet("async-completions/{operationId}/result")]
- public async Task GetCompletionOperation(string instanceId, string operationId) =>
- await _gatekeeperService.GetCompletionOperation(instanceId, operationId);
+ public async Task GetCompletionOperationResult(string instanceId, string operationId) =>
+ await _gatekeeperService.GetCompletionOperationResult(instanceId, operationId);
}
}
diff --git a/src/dotnet/Orchestration/Interfaces/IOrchestrationService.cs b/src/dotnet/Orchestration/Interfaces/IOrchestrationService.cs
index eff83399cf..c0daa1a613 100644
--- a/src/dotnet/Orchestration/Interfaces/IOrchestrationService.cs
+++ b/src/dotnet/Orchestration/Interfaces/IOrchestrationService.cs
@@ -28,16 +28,16 @@ public interface IOrchestrationService
///
/// The FoundationaLLM instance id.
/// The completion request containing the user prompt and message history.
- /// Returns an object containing the OperationId and Status.
- Task StartCompletionOperation(string instanceId, CompletionRequest completionRequest);
+ /// Returns an object containing the OperationId and Status.
+ Task StartCompletionOperation(string instanceId, CompletionRequest completionRequest);
///
/// Gets the status of a completion operation.
///
/// The FoundationaLLM instance id.
- /// The OperationId to retrieve the status for.
- /// Returns an object containing the OperationId and Status.
- Task GetCompletionOperationStatus(string instanceId, string operationId);
+ /// The OperationId for which to retrieve the status.
+ /// Returns an object containing the OperationId and Status.
+ Task GetCompletionOperationStatus(string instanceId, string operationId);
///
/// Gets a completion operation from the Orchestration service.
@@ -45,5 +45,5 @@ public interface IOrchestrationService
/// The FoundationaLLM instance id.
/// The ID of the operation to retrieve.
/// Returns a object.
- Task GetCompletionOperation(string instanceId, string operationId);
+ Task GetCompletionOperationResult(string instanceId, string operationId);
}
diff --git a/src/dotnet/Orchestration/Services/OrchestrationService.cs b/src/dotnet/Orchestration/Services/OrchestrationService.cs
index 9f495a6a19..0cf1edc03b 100644
--- a/src/dotnet/Orchestration/Services/OrchestrationService.cs
+++ b/src/dotnet/Orchestration/Services/OrchestrationService.cs
@@ -33,7 +33,7 @@ public class OrchestrationService : IOrchestrationService
///
/// Constructor for the Orchestration Service.
///
- /// A list of of resource providers hashed by resource provider name.
+ /// A list of resource providers hashed by resource provider name.
/// The managing the internal and external LLM orchestration services.
/// The call context of the request being handled.
/// The used to retrieve app settings from configuration.
@@ -101,15 +101,15 @@ public async Task GetCompletion(string instanceId, Completio
}
///
- public async Task StartCompletionOperation(string instanceId, CompletionRequest completionRequest) =>
+ public async Task StartCompletionOperation(string instanceId, CompletionRequest completionRequest) =>
// TODO: Need to call State API to start the operation.
throw new NotImplementedException();
///
- public Task GetCompletionOperationStatus(string instanceId, string operationId) => throw new NotImplementedException();
+ public Task GetCompletionOperationStatus(string instanceId, string operationId) => throw new NotImplementedException();
///
- public async Task GetCompletionOperation(string instanceId, string operationId) =>
+ public async Task GetCompletionOperationResult(string instanceId, string operationId) =>
// TODO: Need to call State API to get the operation.
throw new NotImplementedException();
diff --git a/src/dotnet/OrchestrationAPI/Controllers/CompletionsController.cs b/src/dotnet/OrchestrationAPI/Controllers/CompletionsController.cs
index eca2b20c70..cb8dda451c 100644
--- a/src/dotnet/OrchestrationAPI/Controllers/CompletionsController.cs
+++ b/src/dotnet/OrchestrationAPI/Controllers/CompletionsController.cs
@@ -38,12 +38,12 @@ public async Task GetCompletion(string instanceId, [FromBody
///
/// The FoundationaLLM instance id.
/// The completion request containing the user prompt and message history.
- /// Returns an object containing the OperationId and Status.
+ /// Returns an object containing the OperationId and Status.
[HttpPost("async-completions")]
- public async Task> StartCompletionOperation(string instanceId, CompletionRequest completionRequest)
+ public async Task> StartCompletionOperation(string instanceId, CompletionRequest completionRequest)
{
- var state = await _orchestrationService.StartCompletionOperation(instanceId, completionRequest);
- return Accepted(state);
+ var longRunningOperation = await _orchestrationService.StartCompletionOperation(instanceId, completionRequest);
+ return Accepted(longRunningOperation);
}
///
@@ -51,9 +51,9 @@ public async Task> StartCompletionOperation(string
///
/// The FoundationaLLM instance id.
/// The OperationId for which to retrieve the status.
- /// Returns an object containing the OperationId and Status.
+ /// Returns an object containing the OperationId and Status.
[HttpGet("async-completions/{operationId}/status")]
- public async Task GetCompletionOperationStatus(string instanceId, string operationId) =>
+ public async Task GetCompletionOperationStatus(string instanceId, string operationId) =>
await _orchestrationService.GetCompletionOperationStatus(instanceId, operationId);
///
@@ -63,8 +63,8 @@ public async Task GetCompletionOperationStatus(string instanceId
/// The ID of the operation to retrieve.
/// Returns a completion response
[HttpGet("async-completions/{operationId}/result")]
- public async Task GetCompletionOperation(string instanceId, string operationId) =>
- await _orchestrationService.GetCompletionOperation(instanceId, operationId);
+ public async Task GetCompletionOperationResult(string instanceId, string operationId) =>
+ await _orchestrationService.GetCompletionOperationResult(instanceId, operationId);
}
}
diff --git a/src/ui/UserPortal/components/ChatThread.vue b/src/ui/UserPortal/components/ChatThread.vue
index 0f95c34339..aab8f67ef2 100644
--- a/src/ui/UserPortal/components/ChatThread.vue
+++ b/src/ui/UserPortal/components/ChatThread.vue
@@ -46,6 +46,7 @@
diff --git a/src/ui/UserPortal/js/api.ts b/src/ui/UserPortal/js/api.ts
index e59f06efda..d308c9f0be 100644
--- a/src/ui/UserPortal/js/api.ts
+++ b/src/ui/UserPortal/js/api.ts
@@ -72,6 +72,71 @@ export default {
}
},
+ /**
+ * Starts a long-running process by making a POST request to the specified URL with the given request body.
+ * @param url - The URL to send the POST request to.
+ * @param requestBody - The request body to send with the POST request.
+ * @returns A Promise that resolves to the operation ID if the process is successfully started.
+ * @throws An error if the process fails to start.
+ */
+ async startLongRunningProcess(url: string, requestBody: any) {
+ const options = {
+ method: 'POST',
+ body: JSON.stringify(requestBody),
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${await this.getBearerToken()}`
+ }
+ };
+
+ try {
+ const response = await $fetch(`${this.apiUrl}${url}`, options);
+ if (response.status === 202) {
+ return response.operationId;
+ } else {
+ throw new Error('Failed to start process');
+ }
+ } catch (error) {
+ throw new Error(this.formatError(error));
+ }
+ },
+
+ /**
+ * Checks the status of a process operation.
+ * @param operationId - The ID of the operation to check.
+ * @returns A Promise that resolves to the response from the server.
+ * @throws If an error occurs during the API call.
+ */
+ async checkProcessStatus(operationId: string) {
+ try {
+ const response = await $fetch(`/instances/${this.instanceId}/async-completions/${operationId}/status`, {
+ method: 'GET',
+ headers: {
+ 'Authorization': `Bearer ${await this.getBearerToken()}`
+ }
+ });
+
+ return response;
+ } catch (error) {
+ throw new Error(this.formatError(error));
+ }
+ },
+
+ /**
+ * Polls for the completion of an operation.
+ * @param operationId - The ID of the operation to poll for completion.
+ * @returns A promise that resolves to the result of the operation when it is completed.
+ */
+ async pollForCompletion(operationId: string) {
+ while (true) {
+ const status = await this.checkProcessStatus(operationId);
+ if (status.isCompleted) {
+ return status.result;
+ }
+ await new Promise(resolve => setTimeout(resolve, 2000)); // Poll every 2 seconds
+ }
+ },
+
/**
* Retrieves the chat sessions from the API.
* @returns {Promise>} A promise that resolves to an array of sessions.
@@ -180,10 +245,17 @@ export default {
settings: null,
attachments: attachments
};
- return (await this.fetch(`/instances/${this.instanceId}/completions`, {
- method: 'POST',
- body: orchestrationRequest,
- })) as string;
+
+ if (agent.long_running) {
+ const operationId = await this.startLongRunningProcess(`/instances/${this.instanceId}/async-completions`,
+ orchestrationRequest);
+ return this.pollForCompletion(operationId);
+ } else {
+ return (await this.fetch(`/instances/${this.instanceId}/completions`, {
+ method: 'POST',
+ body: orchestrationRequest,
+ })) as string;
+ }
},
/**
diff --git a/src/ui/UserPortal/js/eventBus.ts b/src/ui/UserPortal/js/eventBus.ts
new file mode 100644
index 0000000000..4b06ecd047
--- /dev/null
+++ b/src/ui/UserPortal/js/eventBus.ts
@@ -0,0 +1,5 @@
+import mitt from 'mitt';
+
+const emitter = mitt();
+
+export default emitter;
diff --git a/src/ui/UserPortal/js/types/index.ts b/src/ui/UserPortal/js/types/index.ts
index 43fa55cc7a..45e5d30855 100644
--- a/src/ui/UserPortal/js/types/index.ts
+++ b/src/ui/UserPortal/js/types/index.ts
@@ -63,6 +63,7 @@ export interface Agent {
name: string;
object_id: string;
description: string;
+ long_running: boolean;
orchestration_settings?: OrchestrationSettings;
}
diff --git a/src/ui/UserPortal/package-lock.json b/src/ui/UserPortal/package-lock.json
index 40f09efdaf..40c582c25a 100644
--- a/src/ui/UserPortal/package-lock.json
+++ b/src/ui/UserPortal/package-lock.json
@@ -15,6 +15,7 @@
"javascript-time-ago": "^2.5.9",
"marked": "^13.0.2",
"marked-highlight": "^2.1.3",
+ "mitt": "^3.0.1",
"pinia": "^2.1.7",
"primeicons": "^6.0.1",
"primevue": "^3.35.0",
@@ -10258,8 +10259,7 @@
"node_modules/mitt": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
- "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
- "dev": true
+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
},
"node_modules/mkdirp": {
"version": "1.0.4",
diff --git a/src/ui/UserPortal/package.json b/src/ui/UserPortal/package.json
index 2b6943bcb8..c97334cf0d 100644
--- a/src/ui/UserPortal/package.json
+++ b/src/ui/UserPortal/package.json
@@ -36,6 +36,7 @@
"javascript-time-ago": "^2.5.9",
"marked": "^13.0.2",
"marked-highlight": "^2.1.3",
+ "mitt": "^3.0.1",
"pinia": "^2.1.7",
"primeicons": "^6.0.1",
"primevue": "^3.35.0",
diff --git a/src/ui/UserPortal/stores/appStore.ts b/src/ui/UserPortal/stores/appStore.ts
index 37b6e32811..f6a32d2662 100644
--- a/src/ui/UserPortal/stores/appStore.ts
+++ b/src/ui/UserPortal/stores/appStore.ts
@@ -3,6 +3,7 @@ import { useAppConfigStore } from './appConfigStore';
import { useAuthStore } from './authStore';
import type { Session, Message, Agent, ResourceProviderGetResult, Attachment } from '@/js/types';
import api from '@/js/api';
+import eventBus from '@/js/eventBus';
export const useAppStore = defineStore('app', {
state: () => ({
@@ -14,6 +15,7 @@ export const useAppStore = defineStore('app', {
selectedAgents: new Map(),
lastSelectedAgent: null as ResourceProviderGetResult | null,
attachments: [] as Attachment[],
+ longRunningOperations: new Map(), // sessionId -> operationId
}),
getters: {},
@@ -150,6 +152,12 @@ export const useAppStore = defineStore('app', {
return this.selectedAgents.set(session.id, agent);
},
+ /**
+ * Sends a message to the Core API.
+ *
+ * @param text - The text of the message to send.
+ * @returns A Promise that resolves when the message is sent.
+ */
async sendMessage(text: string) {
if (!text) return;
@@ -184,13 +192,28 @@ export const useAppStore = defineStore('app', {
};
this.currentMessages.push(tempAssistantMessage);
- await api.sendMessage(
- this.currentSession!.id,
- text,
- this.getSessionAgent(this.currentSession!).resource,
- this.attachments.map(attachment => String(attachment.id)), // Convert attachments to an array of strings
- );
- await this.getMessages();
+ const agent = this.getSessionAgent(this.currentSession!).resource;
+ if (agent.long_running) {
+ // Handle long-running operations
+ const operationId = await api.startLongRunningProcess('/completions', {
+ session_id: this.currentSession!.id,
+ user_prompt: text,
+ agent_name: agent.name,
+ settings: null,
+ attachments: this.attachments.map(attachment => String(attachment.id))
+ });
+
+ this.longRunningOperations.set(this.currentSession!.id, operationId);
+ this.pollForCompletion(this.currentSession!.id, operationId);
+ } else {
+ await api.sendMessage(
+ this.currentSession!.id,
+ text,
+ agent,
+ this.attachments.map(attachment => String(attachment.id)),
+ );
+ await this.getMessages();
+ }
// Update the session name based on the message sent.
if (this.currentMessages.length === 2) {
@@ -202,6 +225,25 @@ export const useAppStore = defineStore('app', {
// the generate session name already renames the session in the backend
this.currentSession!.name = newSessionName;
}
+ },
+
+ /**
+ * Polls for the completion of a long-running operation.
+ *
+ * @param sessionId - The session ID associated with the operation.
+ * @param operationId - The ID of the operation to check for completion.
+ */
+ async pollForCompletion(sessionId: string, operationId: string) {
+ while (true) {
+ const status = await api.checkProcessStatus(operationId);
+ if (status.isCompleted) {
+ this.longRunningOperations.delete(sessionId);
+ eventBus.emit('operation-completed', { sessionId, operationId });
+ await this.getMessages();
+ break;
+ }
+ await new Promise(resolve => setTimeout(resolve, 2000)); // Poll every 2 seconds
+ }
},
async rateMessage(messageToRate: Message, isLiked: Message['rating']) {