-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
746 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import Constants from '../constants'; | ||
import { MindsDbError } from '../errors'; | ||
import AgentCompletion from './agentCompletion'; | ||
import AgentsRestApiClient from './agentsRestApiClient'; | ||
|
||
/** | ||
* Represents an agent in MindsDB. | ||
*/ | ||
export default class Agent { | ||
/** Project name to which agent belongs to */ | ||
project: string; | ||
|
||
/** Agent name */ | ||
name: string; | ||
/** Model name */ | ||
model: string; | ||
/** Skills of the agent */ | ||
skills: Array<string>; | ||
/** Additional parameters */ | ||
params: any; | ||
/** Rest API client to use for executing agent operations */ | ||
agentsRestApiClient: AgentsRestApiClient; | ||
|
||
/** | ||
* Creates a new agent. | ||
* | ||
* @param {string} project - Project name to which agent belongs to | ||
* @param {string} name - Agent name | ||
* @param {string} model - Model name | ||
* @param {Array<string>} skills - Skills of the agent | ||
* @param {any} params - Additional parameters | ||
* @param {AgentsRestApiClient} agentsRestApiClient - Rest API client to use for executing agent operations | ||
*/ | ||
constructor( | ||
project: string, | ||
name: string, | ||
model: string, | ||
skills: Array<string>, | ||
params: any, | ||
agentsRestApiClient: AgentsRestApiClient | ||
) { | ||
this.project = project; | ||
this.name = name; | ||
this.model = model; | ||
this.skills = skills; | ||
this.params = params; | ||
this.agentsRestApiClient = agentsRestApiClient; | ||
} | ||
|
||
/** | ||
* Creates an agent from a JSON object. | ||
* | ||
* @param {string} project - Project name to which agent belongs to | ||
* @param {any} json - JSON object representing the agent | ||
* @param {AgentsRestApiClient} agentsRestApiClient - Rest API client to use for executing agent operations | ||
* @returns {Agent} - The created agent | ||
*/ | ||
static fromJson( | ||
project: string, | ||
json: any, | ||
agentsRestApiClient: AgentsRestApiClient | ||
): Agent { | ||
return new Agent( | ||
project, | ||
json.name, | ||
json.model, | ||
json.skills.map((skill: any) => skill.name), | ||
json.params || {}, | ||
agentsRestApiClient | ||
); | ||
} | ||
|
||
/** | ||
* Gets the agent completion. | ||
* | ||
* @param {Array<any>} messages - Messages to send to the agent | ||
* @returns {Promise<AgentCompletion>} - The agent completion | ||
*/ | ||
async completion(messages: Array<any>): Promise<AgentCompletion> { | ||
const baseUrl = | ||
this.agentsRestApiClient.client.defaults.baseURL || | ||
Constants.BASE_CLOUD_API_ENDPOINT; | ||
const agentsUrl = `${baseUrl}${Constants.BASE_PROJECTS_URI}/${this.project}/agents/${this.name}/completions`; | ||
|
||
try { | ||
const response = await this.agentsRestApiClient.client.post(agentsUrl, { | ||
messages: messages, | ||
}); | ||
|
||
const content: string = response.data.message.content; | ||
const context: Array<string> = response.data.message.context || []; | ||
return new AgentCompletion(content, context); | ||
} catch (error) { | ||
throw MindsDbError.fromHttpError(error, agentsUrl); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* Represents the completion of an agent with content and context. | ||
*/ | ||
export default class AgentCompletion { | ||
/** | ||
* The content of the agent completion. | ||
*/ | ||
content: string; | ||
|
||
/** | ||
* The context in which the agent completion is made. | ||
*/ | ||
context: Array<string>; | ||
|
||
/** | ||
* Creates an instance of AgentCompletion. | ||
* @param {string} content - The content of the agent completion. | ||
* @param {Array<string>} context - The context in which the agent completion is made. | ||
*/ | ||
constructor(content: string, context: Array<string>) { | ||
this.content = content; | ||
this.context = context; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import Agent from './agent'; | ||
|
||
/** | ||
* Abstract class representing the API client for managing agents. | ||
*/ | ||
export default abstract class AgentsApiClient { | ||
/** | ||
* Retrieves all agents for a given project. | ||
* @param {string} project - The name of the project. | ||
* @throws {MindsDbError} If the agents cannot be retrieved. | ||
* @returns {Promise<Array<Agent>>} A promise that resolves to an array of agents. | ||
*/ | ||
abstract getAllAgents(project: string): Promise<Array<Agent>>; | ||
|
||
/** | ||
* Retrieves a specific agent by its ID. | ||
* @param {string} project - The name of the project. | ||
* @param {string} agentId - The ID of the agent. | ||
* @throws {MindsDbError} If the agent does not exist. | ||
* @returns {Promise<Agent>} A promise that resolves to the agent. | ||
*/ | ||
abstract getAgent(project: string, agentId: string): Promise<Agent>; | ||
|
||
/** | ||
* Creates a new agent. | ||
* @param {string} project - The name of the project. | ||
* @param {string} name - The name of the agent. | ||
* @param {string} model - The model of the agent. | ||
* @param {string} provider - The provider of the agent. | ||
* @param {Array<string>} skills - An array of skills for the agent. | ||
* @param {any} [params] - Optional parameters for the agent. | ||
* @throws {MindsDbError} If the agent cannot be created. | ||
* @returns {Promise<Agent>} A promise that resolves to the created agent. | ||
*/ | ||
abstract createAgent( | ||
project: string, | ||
name: string, | ||
model: string, | ||
provider: string, | ||
skills: Array<string>, | ||
params?: any | ||
): Promise<Agent>; | ||
|
||
/** | ||
* Updates an existing agent. | ||
* @param {string} project - The name of the project. | ||
* @param {string} agentName - The current name of the agent. | ||
* @param {string} [updatedName] - The new name of the agent (optional). | ||
* @param {string} [updatedModel] - The new model of the agent (optional). | ||
* @param {Array<string>} [updatedSkills] - An array of updated skills for the agent (optional). | ||
* @param {any} [updatedParams] - Optional updated parameters for the agent. | ||
* @throws {MindsDbError} If the agent cannot be updated. | ||
* @returns {Promise<Agent>} A promise that resolves to the updated agent. | ||
*/ | ||
abstract updateAgent( | ||
project: string, | ||
agentName: string, | ||
updatedName?: string, | ||
updatedModel?: string, | ||
updatedSkills?: Array<string>, | ||
updatedParams?: any | ||
): Promise<Agent>; | ||
|
||
/** | ||
* Deletes an agent. | ||
* @param {string} project - The name of the project. | ||
* @param {string} agent - The name of the agent to delete. | ||
* @throws {MindsDbError} If the agent cannot be deleted. | ||
* @returns {Promise<void>} A promise that resolves when the agent is deleted. | ||
*/ | ||
abstract deleteAgent(project: string, agent: string): Promise<void>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import AgentsRestApiClient from './agentsRestApiClient'; | ||
|
||
export default { AgentsRestApiClient }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
import { Axios } from 'axios'; | ||
import Constants from '../constants'; | ||
import { MindsDbError } from '../errors'; | ||
import Agent from './agent'; | ||
import AgentsApiClient from './agentsApiClient'; | ||
|
||
const DEFAULT_LLM_PROMPT = | ||
"Answer the user's question in a helpful way: {{question}}"; | ||
const DEFAULT_LLM_MODEL = 'gpt-4o'; | ||
|
||
/** Implementation of AgentsApiClient that goes through the REST API */ | ||
export default class AgentsRestApiClient extends AgentsApiClient { | ||
/** Axios client to use for making HTTP requests */ | ||
client: Axios; | ||
|
||
/** | ||
* Creates a new AgentsRestApiClient. | ||
* | ||
* @param {Axios} client - Axios client to use for making HTTP requests | ||
*/ | ||
constructor(client: Axios) { | ||
super(); | ||
this.client = client; | ||
} | ||
|
||
private getAgentsUrl(project: string): string { | ||
const baseUrl = | ||
this.client.defaults.baseURL || Constants.BASE_CLOUD_API_ENDPOINT; | ||
const agentsUrl = `${baseUrl}${Constants.BASE_PROJECTS_URI}/${project}/agents`; | ||
return agentsUrl; | ||
} | ||
|
||
/** | ||
* Retrieves all agents for a given project. | ||
* | ||
* @param project Project name to which agent belongs to | ||
* @returns {Promise<Array<Agent>>} A promise that resolves to an array of agents. | ||
*/ | ||
override async getAllAgents(project: string): Promise<Array<Agent>> { | ||
const agentsUrl = this.getAgentsUrl(project); | ||
try { | ||
const agentsResponse = await this.client.get(agentsUrl); | ||
if (!agentsResponse.data) { | ||
return []; | ||
} | ||
return agentsResponse.data.map((agent: any) => | ||
Agent.fromJson(project, agent, this) | ||
); | ||
} catch (error) { | ||
throw MindsDbError.fromHttpError(error, agentsUrl); | ||
} | ||
} | ||
|
||
/** | ||
* Retrieves a specific agent by its name. | ||
* | ||
* @param {string} project Project name to which agent belongs to | ||
* @param {string} agent Agent name to retrieve | ||
* @returns {Promise<Agent>} A promise that resolves to the agent. | ||
*/ | ||
override async getAgent(project: string, agent: string): Promise<Agent> { | ||
const agentsUrl = this.getAgentsUrl(project) + `/${agent}`; | ||
try { | ||
const agentResponse = await this.client.get(agentsUrl); | ||
return Agent.fromJson(project, agentResponse.data, this); | ||
} catch (error) { | ||
throw MindsDbError.fromHttpError(error, agentsUrl); | ||
} | ||
} | ||
|
||
/** | ||
* Creates a new agent. | ||
* | ||
* @param {string} project Project name to which agent belongs to | ||
* @param {string} name Agent name to create | ||
* @param {string} [model] Model to use for the agent | ||
* @param {string} [provider] Provider to use for the agent | ||
* @param {Array<string>} [skills] Skills to assign to the agent | ||
* @param {any} [params] Additional parameters for the agent | ||
* @returns {Promise<Agent>} A promise that resolves to the created agent. | ||
*/ | ||
override async createAgent( | ||
project: string, | ||
name: string, | ||
model?: string, | ||
provider?: string, | ||
skills?: Array<string>, | ||
params?: any | ||
): Promise<Agent> { | ||
const agentsUrl = this.getAgentsUrl(project); | ||
|
||
try { | ||
const agentsParams: any = params ? { ...params } : {}; | ||
if (!agentsParams.hasOwnProperty('prompt_template')) { | ||
agentsParams['prompt_template'] = DEFAULT_LLM_PROMPT; | ||
} | ||
|
||
const agent: { | ||
name: string; | ||
model_name?: string; | ||
skills?: Array<string>; | ||
params?: any; | ||
provider?: string | null; | ||
} = { | ||
name: name, | ||
model_name: model || DEFAULT_LLM_MODEL, | ||
skills: skills || [], | ||
provider: provider || null, | ||
params: agentsParams, | ||
}; | ||
|
||
const agentResponse = await this.client.post(agentsUrl, { agent }); | ||
|
||
return Agent.fromJson(project, agentResponse.data, this); | ||
} catch (error) { | ||
throw MindsDbError.fromHttpError(error, agentsUrl); | ||
} | ||
} | ||
|
||
/** | ||
* Updates an existing agent. | ||
* | ||
* @param {string} project Project name to which agent belongs to | ||
* @param {string} agentName Name of the agent to update | ||
* @param {string} [updatedName] New name for the agent | ||
* @param {string} [updatedModel] New model for the agent | ||
* @param {Array<string>} [updatedSkills] New skills for the agent | ||
* @param {any} [updatedParams] New parameters for the agent | ||
* @returns {Promise<Agent>} A promise that resolves to the updated agent. | ||
*/ | ||
override async updateAgent( | ||
project: string, | ||
agentName: string, | ||
updatedName?: string, | ||
updatedModel?: string, | ||
updatedSkills?: Array<string>, | ||
updatedParams?: any | ||
): Promise<Agent> { | ||
const agentsUrl = this.getAgentsUrl(project) + `/${agentName}`; | ||
try { | ||
const agent = await this.getAgent(project, agentName); | ||
const updatedSkillSet = new Set<string>(); | ||
if (updatedSkills) { | ||
updatedSkills?.forEach((skill) => updatedSkillSet.add(skill)); | ||
} | ||
const existingSkillSet = new Set<string>(agent.skills); | ||
const skillsToAddSet = new Set<string>(updatedSkillSet); | ||
existingSkillSet.forEach((skill) => { | ||
if (skillsToAddSet.has(skill)) { | ||
skillsToAddSet.delete(skill); | ||
} | ||
}); | ||
const skillsToRemoveSet = new Set<string>(existingSkillSet); | ||
updatedSkillSet.forEach((skill) => { | ||
if (skillsToRemoveSet.has(skill)) { | ||
skillsToRemoveSet.delete(skill); | ||
} | ||
}); | ||
|
||
const updatedAgent: { | ||
name: string; | ||
model_name: string; | ||
skills_to_add: Array<string>; | ||
skills_to_remove: Array<string>; | ||
params: any; | ||
} = { | ||
name: updatedName || agent.name, | ||
model_name: updatedModel || agent.model, | ||
skills_to_add: Array.from(skillsToAddSet), | ||
skills_to_remove: Array.from(skillsToRemoveSet), | ||
params: updatedParams || agent.params, | ||
}; | ||
|
||
const agentResponse = await this.client.put(agentsUrl, { | ||
agent: updatedAgent, | ||
}); | ||
|
||
return Agent.fromJson(project, agentResponse.data, this); | ||
} catch (error) { | ||
throw MindsDbError.fromHttpError(error, agentsUrl); | ||
} | ||
} | ||
|
||
/** | ||
* Deletes a specific agent by its name. | ||
* | ||
* @param {string} project Project name to which agent belongs to | ||
* @param {string} agent Agent name to delete | ||
*/ | ||
override async deleteAgent(project: string, agent: string): Promise<void> { | ||
const agentsUrl = this.getAgentsUrl(project) + `/${agent}`; | ||
try { | ||
await this.client.delete(agentsUrl); | ||
} catch (error) { | ||
throw MindsDbError.fromHttpError(error, agentsUrl); | ||
} | ||
} | ||
} |
Oops, something went wrong.