UNPKG

@memberjunction/ai-agent-manager-actions

Version:

Agent Management actions for creating and managing AI agents in MemberJunction

277 lines (245 loc) 9.75 kB
import { ActionResultSimple, RunActionParams } from "@memberjunction/actions-base"; import { BaseAction } from "@memberjunction/actions"; import { BaseEntity, Metadata, LogError, UserInfo, RunView } from "@memberjunction/core"; import { AIAgentEntity, AIAgentTypeEntity, AIPromptEntity, AIPromptEntityExtended, AIAgentPromptEntity, ActionEntity } from "@memberjunction/core-entities"; /** * Abstract base class for agent management actions. * Provides common functionality for validating permissions, loading entities, * and managing agent metadata. Only the Agent Manager agent should be able * to execute these actions. */ export abstract class BaseAgentManagementAction extends BaseAction { /** * Validates that the action is being called by the Agent Manager agent */ protected async validateAgentManagerPermission(params: RunActionParams): Promise<ActionResultSimple | null> { // In a production system, this would check the calling agent's identity // For now, we'll add a comment about the security check // TODO: Implement proper agent identity verification // Check if the action is being called with proper context if (!params.ContextUser) { return { Success: false, ResultCode: 'PERMISSION_DENIED', Message: 'User context is required for agent management actions' }; } return null; // Permission granted } /** * Extract and validate a string parameter */ protected getStringParam(params: RunActionParams, paramName: string, required: boolean = true): { value?: string; error?: ActionResultSimple } { const param = params.Params.find(p => p.Name.trim().toLowerCase() === paramName.trim().toLowerCase()); if (!param || !param.Value) { if (required) { return { error: { Success: false, ResultCode: 'VALIDATION_ERROR', Message: `${paramName} parameter is required` } }; } return { value: undefined }; } return { value: param.Value as string }; } /** * Extract and validate an object parameter */ protected getObjectParam(params: RunActionParams, paramName: string, required: boolean = true): { value?: Record<string, any>; error?: ActionResultSimple } { const param = params.Params.find(p => p.Name.trim().toLowerCase() === paramName.toLowerCase()); if (!param || !param.Value) { if (required) { return { error: { Success: false, ResultCode: 'VALIDATION_ERROR', Message: `${paramName} parameter is required` } }; } return { value: undefined }; } return { value: param.Value as Record<string, any> }; } /** * Get metadata instance */ protected getMetadata(): Metadata { return new Metadata(); } /** * Load an AI Agent entity by ID */ protected async loadAgent(agentID: string, contextUser: any): Promise<{ agent?: AIAgentEntity; error?: ActionResultSimple; }> { try { const md = this.getMetadata(); const agent = await md.GetEntityObject<AIAgentEntity>('AI Agents', contextUser); if (!agent) { return { error: { Success: false, ResultCode: 'FAILED', Message: 'Failed to create AI Agent entity object' } }; } const loaded = await agent.Load(agentID); if (!loaded) { return { error: { Success: false, ResultCode: 'NOT_FOUND', Message: `Agent with ID '${agentID}' not found` } }; } return { agent }; } catch (e) { return { error: { Success: false, ResultCode: 'ERROR', Message: `Error loading agent: ${e instanceof Error ? e.message : 'Unknown error'}` } }; } } /** * Validate agent type exists */ protected async validateAgentType(typeID: string, contextUser: any): Promise<{ type?: AIAgentTypeEntity; error?: ActionResultSimple; }> { try { const md = this.getMetadata(); const agentType = await md.GetEntityObject<AIAgentTypeEntity>('MJ: AI Agent Types', contextUser); if (!agentType) { return { error: { Success: false, ResultCode: 'FAILED', Message: 'Failed to create AI Agent Type entity object' } }; } const loaded = await agentType.Load(typeID); if (!loaded) { return { error: { Success: false, ResultCode: 'INVALID_TYPE', Message: `Agent Type with ID '${typeID}' not found` } }; } return { type: agentType }; } catch (e) { return { error: { Success: false, ResultCode: 'ERROR', Message: `Error validating agent type: ${e instanceof Error ? e.message : 'Unknown error'}` } }; } } /** * Common error handler */ protected handleError(error: any, operation: string): ActionResultSimple { const message = error instanceof Error ? error.message : 'Unknown error'; LogError(`Agent Management Action error during ${operation}: ${message}`); return { Success: false, ResultCode: 'ERROR', Message: `Failed to ${operation}: ${message}` }; } /** * Creates a prompt and associates it with an agent */ protected async createAndAssociatePrompt( agent: AIAgentEntity, promptText: string, contextUser: UserInfo ): Promise<{ success: boolean; promptId?: string; error?: string }> { try { const md = this.getMetadata(); // Create the prompt const prompt = await md.GetEntityObject<AIPromptEntityExtended>('AI Prompts', contextUser); if (!prompt) { return { success: false, error: 'Failed to create AI Prompt entity object' }; } prompt.NewRecord(); prompt.Name = `${agent.Name} System Prompt`; prompt.Description = `System prompt for ${agent.Name} agent`; prompt.TypeID = await this.getPromptTypeID('Chat', contextUser); prompt.Status = 'Active'; prompt.ResponseFormat = 'JSON'; prompt.PromptRole = 'System'; prompt.PromptPosition = 'First'; prompt.TemplateText = promptText; // This uses the extended property const promptSaved = await prompt.Save(); if (!promptSaved) { return { success: false, error: prompt.LatestResult?.Message || 'Failed to save prompt' }; } // Create the agent-prompt association const agentPrompt = await md.GetEntityObject<AIAgentPromptEntity>('AI Agent Prompts', contextUser); if (!agentPrompt) { return { success: false, error: 'Failed to create AI Agent Prompt entity object' }; } agentPrompt.NewRecord(); agentPrompt.AgentID = agent.ID; agentPrompt.PromptID = prompt.ID; agentPrompt.ExecutionOrder = 1; agentPrompt.Status = 'Active'; const associationSaved = await agentPrompt.Save(); if (!associationSaved) { // Try to clean up the prompt since association failed await prompt.Delete(); return { success: false, error: agentPrompt.LatestResult?.Message || 'Failed to associate prompt with agent' }; } return { success: true, promptId: prompt.ID }; } catch (e) { return { success: false, error: e instanceof Error ? e.message : 'Unknown error creating prompt' }; } } /** * Gets the prompt type ID for a given type name */ private async getPromptTypeID(typeName: string, contextUser: UserInfo): Promise<string> { const rv = new RunView(); const result = await rv.RunView({ EntityName: 'AI Prompt Types', ExtraFilter: `Name = '${typeName}'`, MaxRows: 1, ResultType: 'entity_object' }, contextUser); if (result.Success && result.Results && result.Results.length > 0) { return result.Results[0].ID; } throw new Error(`Prompt type '${typeName}' not found`); } }