# AI Process Builder + Chat Orchestrator A complete implementation of tenant-scoped AI process automation where admins design LangGraph-compiled workflows via React Flow UI, and end-users execute them through a Deep Agent chat orchestrator with deterministic, audited execution. ## Architecture Overview ### Backend Components #### 1. **Deep Agent Orchestrator** ([deep-agent.orchestrator.ts](backend/src/ai-processes/deep-agent.orchestrator.ts)) - Uses LangChain/OpenAI to intelligently select processes - Extracts structured inputs from natural language - Generates friendly confirmation messages - Three-step workflow: discover → select → extract → execute #### 2. **Graph Compiler** ([ai-processes.compiler.ts](backend/src/ai-processes/ai-processes.compiler.ts)) - Validates ReactFlow JSON graphs (Start/End nodes, reachability, cycles) - Compiles to LangGraph-compatible state machines - Validates tool allowlist and JSON schemas (Ajv) - Persists compiled artifact for versioned execution #### 3. **Runtime Executor** ([ai-processes.runner.ts](backend/src/ai-processes/ai-processes.runner.ts)) - Executes compiled graphs deterministically - Implements 4 node types: LLMDecisionNode, ToolNode, HumanInputNode, End - Handles conditional edges via jsonlogic - Emits real-time events for streaming updates #### 4. **Tool Registry** ([tools/tool-registry.ts](backend/src/ai-processes/tools/tool-registry.ts)) - Tenant-scoped tool allowlist (database-backed via AiToolConfig) - Demo tools wrapping ObjectService (findAccount, createAccount, etc.) - Context injection (tenantId, userId, knex) for secure execution #### 5. **Orchestrator Service** ([ai-processes.orchestrator.service.ts](backend/src/ai-processes/ai-processes.orchestrator.service.ts)) - Integrates Deep Agent for process selection - Falls back to standard AI assistant when no processes configured - Manages chat sessions and message history - Streams execution events via SSE ### Frontend Components #### 1. **AIChatBar** ([components/AIChatBar.vue](frontend/components/AIChatBar.vue)) - Updated to call `/ai-processes/chat/messages` endpoint - SSE event stream consumer for real-time updates - Displays process selection, node execution, tool calls - Handles NEED_INPUT events for human-in-the-loop #### 2. **Process Management UI** ([pages/ai-processes/](frontend/pages/ai-processes/)) - List view: displays all processes with versions - Editor view: React Flow integration via iframe + postMessage - Test runner for quick validation #### 3. **React Flow Editor** ([ai-processes-editor/src/App.tsx](frontend/ai-processes-editor/src/App.tsx)) - Node palette: Start, LLMDecisionNode, ToolNode, HumanInputNode, End - Visual graph designer with drag-drop - Auto-saves to parent window via postMessage - Loads existing graphs for editing ### Data Models (Objection.js) ```typescript AiProcess ├── id, tenantId, name, description, latestVersion └── relations: versions[], runs[] AiProcessVersion ├── id, tenantId, processId, version ├── graphJson (ReactFlow definition) └── compiledJson (LangGraph artifact) AiProcessRun ├── id, tenantId, processId, version, status ├── inputJson, outputJson, errorJson, stateJson └── currentNodeId (for resume) AiChatSession ├── id, tenantId, userId └── relations: messages[] AiChatMessage ├── id, sessionId, role, content └── timestamps AiAuditEvent ├── id, tenantId, runId, eventType └── payloadJson (full event data) AiToolConfig ├── id, tenantId, toolName, enabled └── configJson (tool-specific settings) ``` ## Demo Process: Register New Pet A complete workflow demonstrating conditional logic and tool orchestration: 1. **Extract Info** (LLMDecisionNode) - Parses user message for pet + owner details - Outputs structured JSON with validation 2. **Find/Create Account** (Conditional) - Searches for existing account by name/email - Creates new account if not found - Merges results into state 3. **Find/Create Contact** (Conditional) - Searches for existing contact under account - Creates new contact if not found 4. **Create Pet** (ToolNode) - Inserts pet record linked to contact - Returns pet ID ### Seed the Demo Process ```bash cd backend npm run migrate:tenant -- npm run seed:demo-process -- ``` ### Test the Demo Process 1. Navigate to `/ai-processes` in your tenant subdomain 2. Open "Register New Pet" process 3. Click "Test Run" or use the chat bar: ``` User: "Register a dog named Max, breed Golden Retriever, age 3, owned by John Smith, email john@example.com" Agent: 🔄 Selected process: Register New Pet I'll register Max (Golden Retriever, 3 years old) for John Smith. ⚙️ Executing step: Extract Info ✓ Extracted pet details 🔧 Using tool: findAccount ℹ️ Account not found, creating new account 🔧 Using tool: createAccount ✓ Created account for John Smith 🔧 Using tool: findContact ℹ️ Contact not found, creating new contact 🔧 Using tool: createContact ✓ Created contact: John Smith 🔧 Using tool: createPet ✓ Created pet: Max (ID: pet_1234567890) ✅ Process completed successfully! ``` ## API Endpoints ### Process Management (Admin) ```typescript GET /tenants/:tenantId/ai-processes POST /tenants/:tenantId/ai-processes GET /tenants/:tenantId/ai-processes/:id POST /tenants/:tenantId/ai-processes/:id/versions GET /tenants/:tenantId/ai-processes/:id/versions POST /tenants/:tenantId/ai-processes/:id/runs POST /tenants/:tenantId/ai-processes/runs/:runId/resume ``` ### Chat Orchestrator (End User) ```typescript POST /tenants/:tenantId/ai-processes/chat/messages SSE /tenants/:tenantId/ai-processes/stream?sessionId=xxx ``` ## Event Stream Types ```typescript type StreamEvent = | { type: 'agent_started' } | { type: 'processes_listed', data: { count: number } } | { type: 'process_selected', processId: string, version: number } | { type: 'agent_message', data: { message: string } } | { type: 'node_started', nodeId: string } | { type: 'node_completed', nodeId: string } | { type: 'tool_called', toolName: string, nodeId: string } | { type: 'llm_decision', nodeId: string, data: any } | { type: 'need_input', data: { prompt: string, schema: JSONSchema } } | { type: 'final', data: { output: any } } | { type: 'error', data: { error: string } } ``` ## Security & Guardrails ### 1. **Tenancy Isolation** - All queries filtered by `tenantId` (enforced in Objection models) - Tool context includes tenant scope - Database-per-tenant architecture (inherited from platform) ### 2. **Tool Allowlist** - Two-level validation: - Tenant-level: `AiToolConfig` table (enabled tools per tenant) - Compile-time: validates toolName exists in registry - Runtime check before tool execution ### 3. **Schema Validation** - LLMDecisionNode output validated against JSON Schema (Ajv) - HumanInputNode input validated before resume - Graph structure validated at compile time ### 4. **Audit Trail** - Every node execution logged to `ai_audit_events` - Includes: tool calls, LLM decisions, state mutations, errors - Queryable for compliance dashboards ### 5. **Versioning** - Immutable process versions (create-only) - Runs reference specific version number - Graph definition + compiled artifact stored together ## Running the System ### 1. **Run Migrations** ```bash cd backend npm run migrate:tenant -- tenant1 ``` ### 2. **Seed Demo Data** ```bash npm run seed:demo-process -- tenant1 ``` ### 3. **Start Backend** ```bash npm run start:dev ``` ### 4. **Build Editor (if needed)** ```bash cd frontend/ai-processes-editor npm install npm run build ``` ### 5. **Start Frontend** ```bash cd frontend npm run dev ``` ### 6. **Access UI** - Admin UI: `http://tenant1.localhost:3001/ai-processes` - Chat UI: Available in bottom drawer on any page (⌘K to toggle) ## Extension Points ### Adding New Node Types 1. Define type in [ai-processes.types.ts](backend/src/ai-processes/ai-processes.types.ts) 2. Add schema validation in [ai-processes.schemas.ts](backend/src/ai-processes/ai-processes.schemas.ts) 3. Implement executor in [ai-processes.runner.ts](backend/src/ai-processes/ai-processes.runner.ts) 4. Add UI component in React Flow editor ### Adding New Tools 1. Implement handler in [tools/demo-tools.ts](backend/src/ai-processes/tools/demo-tools.ts) 2. Register in `demoTools` export 3. Add to tenant allowlist via UI or seed script 4. Document input/output schema ### Custom LLM Decision Logic Override `llmDecision` callback in [ai-processes.service.ts](backend/src/ai-processes/ai-processes.service.ts): ```typescript llmDecision: async (node, state) => { const prompt = renderTemplate(node.data.promptTemplate, state); const response = await callOpenAI(prompt, node.data.model); return validateAgainstSchema(response, node.data.outputSchema); } ``` ## Troubleshooting ### Process not appearing in chat - Check: `npm run seed:demo-process` completed successfully - Verify: Process exists in database (`select * from ai_processes`) - Check: Tools enabled (`select * from ai_tool_configs`) ### Graph validation errors - Ensure exactly one Start node - Ensure at least one End node - Check all edges reference valid node IDs - Verify tool names match registered tools ### SSE stream not working - Check CORS settings for subdomain routing - Verify `sessionId` returned from initial message - Check browser console for connection errors - Fallback: use polling endpoint (TODO: implement) ## Next Steps 1. **Enhanced Input Extraction**: Use Deep Agent to extract required fields per process 2. **Visual Schema Builder**: UI for JSON Schema creation (drag-drop fields) 3. **Conditional Edge Builder**: Visual jsonlogic editor 4. **Process Analytics**: Dashboard showing run success rates, avg duration 5. **Human-in-Loop UI**: Dynamic form renderer for HumanInputNode 6. **Process Marketplace**: Share processes across tenants (with permissions) 7. **Python Microservice**: Optional Python runtime for native LangGraph support ## License MIT