UNPKG

@memberjunction/ai-agent-manager-actions

Version:

Agent Management actions for creating and managing AI agents in MemberJunction

181 lines (157 loc) 7.6 kB
import { ActionResultSimple, RunActionParams } from "@memberjunction/actions-base"; import { RegisterClass } from "@memberjunction/global"; import { AIAgentEntity, AIPromptEntityExtended, AIAgentPromptEntity } from "@memberjunction/core-entities"; import { BaseAgentManagementAction } from "./base-agent-management.action"; import { AIEngineBase } from "@memberjunction/ai-engine-base"; import { BaseAction } from "@memberjunction/actions"; /** * Creates a new AI agent with specified configuration. * This action is restricted to the Agent Manager agent only. * Supports creating both top-level agents and sub-agents. * Optionally creates and associates a system prompt if PromptText is provided. * * @example * ```typescript * const result = await runAction({ * ActionName: 'Create Agent', * Params: [ * { Name: 'Name', Value: 'Customer Feedback Analyzer' }, * { Name: 'Description', Value: 'Analyzes customer feedback...' }, * { Name: 'Type', Value: 'Loop' }, // Optional, use Type OR TypeID * { Name: 'TypeID', Value: 'loop-agent-type-id' }, // Optional, use Type OR TypeID * { Name: 'PromptText', Value: 'You are a feedback analyzer...' }, // Optional, creates prompt * { Name: 'ParentID', Value: 'parent-agent-id' } // Optional, for sub-agents * ] * }); * // Returns AgentID and optionally PromptID in output params * ``` */ @RegisterClass(BaseAction, "Create Agent") export class CreateAgentAction extends BaseAgentManagementAction { protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> { try { // Validate permission const permissionError = await this.validateAgentManagerPermission(params); if (permissionError) return permissionError; // Extract parameters const nameResult = this.getStringParam(params, 'Name'); if (nameResult.error) return nameResult.error; const descriptionResult = this.getStringParam(params, 'Description'); if (descriptionResult.error) return descriptionResult.error; // Handle Type/TypeID - one is required const typeResult = this.getStringParam(params, 'Type', false); const typeIDResult = this.getStringParam(params, 'TypeID', false); if (!typeResult.value && !typeIDResult.value) { return { Success: false, ResultCode: 'MISSING_PARAMETER', Message: 'Either Type or TypeID parameter is required' }; } // Resolve TypeID if Type was provided let resolvedTypeID: string; if (typeIDResult.value) { resolvedTypeID = typeIDResult.value; } else { // Look up TypeID from Type name const aiEngine = AIEngineBase.Instance; const agentType = aiEngine.AgentTypes.find((t: any) => t.Name.toLowerCase() === typeResult.value!.toLowerCase() ); if (!agentType) { return { Success: false, ResultCode: 'INVALID_TYPE', Message: `Agent type '${typeResult.value}' not found. Available types: ${aiEngine.AgentTypes.map((t: any) => t.Name).join(', ')}` }; } resolvedTypeID = agentType.ID; } const promptTextResult = this.getStringParam(params, 'PromptText', false); if (promptTextResult.error) return promptTextResult.error; const parentIDResult = this.getStringParam(params, 'ParentID', false); if (parentIDResult.error) return parentIDResult.error; // Validate agent type exists const typeValidation = await this.validateAgentType(resolvedTypeID, params.ContextUser); if (typeValidation.error) return typeValidation.error; // Validate parent agent exists if provided if (parentIDResult.value) { const parentValidation = await this.loadAgent(parentIDResult.value, params.ContextUser); if (parentValidation.error) return parentValidation.error; } // Create new agent const md = this.getMetadata(); const agent = await md.GetEntityObject<AIAgentEntity>('AI Agents', params.ContextUser); if (!agent) { return { Success: false, ResultCode: 'FAILED', Message: 'Failed to create AI Agent entity object' }; } // Set agent properties agent.NewRecord(); agent.Name = nameResult.value!; agent.Description = descriptionResult.value!; agent.TypeID = resolvedTypeID; agent.Status = 'Active'; agent.ExecutionOrder = 0; agent.ExposeAsAction = false; // Default to not exposed if (parentIDResult.value) { agent.ParentID = parentIDResult.value; } // Save the agent const saveResult = await agent.Save(); if (saveResult) { // Add output parameter with the new agent ID params.Params.push({ Name: 'AgentID', Value: agent.ID, Type: 'Output' }); // If prompt text was provided, create and associate the prompt if (promptTextResult.value) { const promptResult = await this.createAndAssociatePrompt( agent, promptTextResult.value, params.ContextUser ); if (!promptResult.success) { // Agent was created but prompt failed - return partial success return { Success: true, ResultCode: 'PARTIAL_SUCCESS', Message: `Agent '${agent.Name}' created successfully, but prompt creation failed: ${promptResult.error}`, Params: params.Params }; } // Add prompt ID to output params.Params.push({ Name: 'PromptID', Value: promptResult.promptId, Type: 'Output' }); } return { Success: true, ResultCode: 'SUCCESS', Message: `Successfully created agent '${agent.Name}' with ID ${agent.ID}`, Params: params.Params }; } else { const latestResult = agent.LatestResult; return { Success: false, ResultCode: 'SAVE_FAILED', Message: latestResult?.Message || 'Failed to save agent' }; } } catch (e) { return this.handleError(e, 'create agent'); } } } export function LoadCreateAgentAction() { // This function exists to prevent tree shaking from removing the action class // The side effect of loading this file is that the @RegisterClass decorator runs }