diff --git a/libraries/ai/Agent.js b/libraries/ai/Agent.js deleted file mode 100644 index 93bf9d951..000000000 --- a/libraries/ai/Agent.js +++ /dev/null @@ -1,11 +0,0 @@ -class Agent { - constructor(client) { - this.client = client; - } - - async process(userPrompt, previousMessages, agentResponses = null) { - throw new Error('process() must be implemented by subclass'); - } -} - -module.exports = Agent; diff --git a/libraries/ai/AgentFactory.js b/libraries/ai/AgentFactory.js deleted file mode 100644 index 59d6533b7..000000000 --- a/libraries/ai/AgentFactory.js +++ /dev/null @@ -1,28 +0,0 @@ -const ChatbotAgent = require('./ChatbotAgent'); -const ApiFunctionCallingAgent = require('./ApiFunctionCallingAgent'); -const { getClient } = require('./apiClient'); - -const AGENT_TYPES = Object.freeze({ - ChatbotAgent: 'ChatbotAgent', - ApiFunctionCallingAgent: 'ApiFunctionCallingAgent', - None: 'None' -}); - -class AgentFactory { - static createAgent(type) { - const client = getClient(); - switch (type) { - case AGENT_TYPES.ChatbotAgent: - return new ChatbotAgent(client); - case AGENT_TYPES.ApiFunctionCallingAgent: - return new ApiFunctionCallingAgent(client); - default: - throw new Error(`Unknown agent type: ${type}`); - } - } -} - -module.exports = { - AgentFactory, - AGENT_TYPES -} diff --git a/libraries/ai/ApiFunctionCallingAgent.js b/libraries/ai/ApiFunctionCallingAgent.js deleted file mode 100644 index 350ccd153..000000000 --- a/libraries/ai/ApiFunctionCallingAgent.js +++ /dev/null @@ -1,16 +0,0 @@ -const Agent = require('./Agent'); -const {AGENT_TYPES} = require('./AgentFactory'); - -class ApiFunctionCallingAgent extends Agent { - constructor(client) { - super(client); - this.name = 'ApiFunctionCallingAgent'; //AGENT_TYPES.ApiFunctionCallingAgent; - } - - async process(userPrompt, previousMessages, agentResponses) { - // Use this.client to interact with OpenAI API - return 'API function response'; - } -} - -module.exports = ApiFunctionCallingAgent; diff --git a/libraries/ai/ChatbotAgent.js b/libraries/ai/ChatbotAgent.js deleted file mode 100644 index 3b5f780d5..000000000 --- a/libraries/ai/ChatbotAgent.js +++ /dev/null @@ -1,62 +0,0 @@ -const Agent = require('./Agent'); -const { AGENT_TYPES } = require('./AgentFactory'); -const { getClient, DEPLOYMENT_ID } = require('./apiClient'); - -const CHATBOT_PROMPT = `You are a helpful assistant whose job is to understand an log of interactions that one or - more users has performed within a 3D digital-twin software. Within the software, the users can add various spatial - applications into a scanned environment, to annotate, record, analyze, document, mark-up, and otherwise collaborate - in the space, synchronously or asynchronously. Some of these spatial applications also have functions that you can - activate, which will be provided to you in the form of an API registry. You are a helpful assistant who will answer - questions that the user has about the current and historical state of the space and the interactions that have taken - place within it, and sometimes make use of the API registry to perform actions within the software to fulfill the - user's requests. Here are some key things to know about the system: A "spatial tool" or a "spatial application" - represents a component that users can add to the space. Generally, spatial applications are represented by an icon - in 3D space, and when the user clicks on it the application is opened and can be interacted with. It can then be - closed with an X button or "minimized" (un-focused) with a minimize button. For example, the spatialDraw tool is a - spatial application that, when opened, displays UI that allows the user to annotate the 3D scene. Any number of each - application can be added to the space and coexist at the same time. A user's "focus" changes when they click on - another spatial application icon, allowing them to view and edit the contents of that tool. The term "avatar" in - this system is synonymous with a "connected user", and the list of connected users will be provided to you.`; - -class ChatbotAgent extends Agent { - constructor(client) { - super(client); - this.name = 'ChatbotAgent'; // AGENT_TYPES.ChatbotAgent; - } - - async process(userPrompt, previousMessages, agentResponses) { - // Use this.client to interact with OpenAI API - return this.callOpenAiApi(userPrompt, previousMessages); - } - - async callOpenAiApi(prompt, previousMessages) { - const client = getClient(); - // const apiResponse = await client.completions.create({ - // model: 'davinci-codex', - // prompt: prompt, - // max_tokens: 50 - // }); - // - // return apiResponse.choices[0].text.trim(); - - // const context = this.contextManager.getContext(); - - const messages = [ - // ...Object.values(context.systemMessages), - { role: 'system', content: CHATBOT_PROMPT}, - ...Object.values(previousMessages), - prompt - ]; - - // if (agentResponses) { - // messages.push(...Object.values(agentResponses)); - // } - - let result = await client.getChatCompletions(DEPLOYMENT_ID, messages); - let actualResult = result.choices[0].message.content; - console.log(actualResult); - return actualResult; - } -} - -module.exports = ChatbotAgent; diff --git a/libraries/ai/ContextManager.js b/libraries/ai/ContextManager.js deleted file mode 100644 index aacdb5769..000000000 --- a/libraries/ai/ContextManager.js +++ /dev/null @@ -1,26 +0,0 @@ -class ContextManager { - constructor(systemMessages, userPrompt, previousMessages) { - this.systemMessages = systemMessages; - this.userPrompt = userPrompt; - this.previousMessages = previousMessages; - this.agentResponses = []; - this.agentChain = []; - } - - updateContext(agentName, agentResponse) { - this.agentChain.push(agentName); - this.agentResponses.push(agentResponse); - } - - getContext() { - return { - systemMessages: this.systemMessages, - userPrompt: this.userPrompt, - previousMessages: this.previousMessages, - agentResponses: this.agentResponses, - agentChain: this.agentChain - }; - } -} - -module.exports = ContextManager; diff --git a/libraries/ai/CoordinatorAgent.js b/libraries/ai/CoordinatorAgent.js deleted file mode 100644 index 0916d3538..000000000 --- a/libraries/ai/CoordinatorAgent.js +++ /dev/null @@ -1,118 +0,0 @@ -const { AGENT_TYPES, AgentFactory } = require('./AgentFactory'); -const ContextManager = require('./ContextManager'); -const { getClient, DEPLOYMENT_ID } = require('./apiClient'); - -class CoordinatorAgent { - constructor(systemMessages) { - this.systemMessages = systemMessages; - this.MAX_AGENT_CHAIN_LENGTH = 10; - } - - async decideFirstAgent(_context) { - // Logic to decide the first agent based on initial context - return AGENT_TYPES.ChatbotAgent; // Example initial agent type - } - - async decideNextAgent(context) { - const response = context.agentResponses[context.agentResponses.length - 1]; - - let relevantContext = { - previousMessages: context.previousMessages, - userPrompt: context.userPrompt - }; - const prompt = ` - Given the current context and the last agent's response, decide the next agent to process the request. - Context: ${JSON.stringify(relevantContext)} - Last Response: ${response} - - Choose one of the following options: - - ${AGENT_TYPES.ChatbotAgent} - - ${AGENT_TYPES.ApiFunctionCallingAgent} - - ${AGENT_TYPES.None} (if no further agent is needed) - - Response: - `; - - const openAiResponse = await this.callOpenAiApi({ - role: "user", content: prompt - }); - return this.parseDecision(context.agentChain, openAiResponse); - } - - async callOpenAiApi(prompt) { - const client = getClient(); - // const apiResponse = await client.completions.create({ - // model: 'davinci-codex', - // prompt: prompt, - // max_tokens: 50 - // }); - // - // return apiResponse.choices[0].text.trim(); - - const context = this.contextManager.getContext(); - - const messages = [ - ...Object.values(context.systemMessages), - ...Object.values(context.previousMessages), - prompt - ]; - - // if (agentResponses) { - // messages.push(...Object.values(agentResponses)); - // } - - let result = await client.getChatCompletions(DEPLOYMENT_ID, messages); - let actualResult = result.choices[0].message.content; - console.log(actualResult); - return actualResult; - } - - parseDecision(agentChain, apiResponse) { - let lastAgent = agentChain.length > 0 ? agentChain[agentChain.length - 1] : null; - - // make sure this regex matches the AGENT_TYPES enum - const decisionMatch = apiResponse.match(/(ChatbotAgent|ApiFunctionCallingAgent|None)/); - let decidedAgentName = decisionMatch ? decisionMatch[1] : AGENT_TYPES.None; - - // prevent infinite loops of adding more chatbot agents - if (lastAgent === AGENT_TYPES.ChatbotAgent && decidedAgentName !== AGENT_TYPES.ApiFunctionCallingAgent) { - return AGENT_TYPES.None; - } - - return decidedAgentName; - } - - async process(userPrompt, previousMessages) { - console.log('CoordinatorAgent.process'); - - this.contextManager = new ContextManager(this.systemMessages, userPrompt, previousMessages); - const context = this.contextManager.getContext(); - - let agentChain = []; - let firstAgentType = await this.decideFirstAgent(context); - let firstAgent = AgentFactory.createAgent(firstAgentType); - agentChain.push(firstAgent); - - let firstResponse = await firstAgent.process(userPrompt, previousMessages); - this.contextManager.updateContext(firstAgent.name, firstResponse); - - let nextAgentType = await this.decideNextAgent(this.contextManager.getContext()); - while (nextAgentType !== AGENT_TYPES.None && agentChain.length < this.MAX_AGENT_CHAIN_LENGTH) { - let nextAgent = AgentFactory.createAgent(nextAgentType); - agentChain.push(nextAgent); - - let nextResponse = await nextAgent.process(userPrompt, previousMessages, this.contextManager.getContext().agentResponses); - this.contextManager.updateContext(nextAgent.name, nextResponse); - - nextAgentType = await this.decideNextAgent(this.contextManager.getContext()); - } - - return this.generateFinalResponse(this.contextManager.getContext().agentResponses); - } - - generateFinalResponse(agentResponses) { - return agentResponses.join('\n'); - } -} - -module.exports = CoordinatorAgent; diff --git a/libraries/ai/apiClient.js b/libraries/ai/apiClient.js deleted file mode 100644 index c3297d6ac..000000000 --- a/libraries/ai/apiClient.js +++ /dev/null @@ -1,25 +0,0 @@ -const { OpenAIClient, AzureKeyCredential } = require('@azure/openai'); - -let client; -const DEPLOYMENT_ID = 'gpt-35-turbo-16k'; -// const deploymentId = "gpt-35-turbo-16k"; - -function initClient(endpoint, azureApiKey) { - if (!client) { - client = new OpenAIClient(endpoint, new AzureKeyCredential(azureApiKey)); - } - return client; -} - -function getClient() { - if (!client) { - throw new Error('Client has not been initialized. Call initClient first.'); - } - return client; -} - -module.exports = { - initClient, - getClient, - DEPLOYMENT_ID -};