Files
neo/AI_PROCESS_BUILDER_README.md
2026-01-17 22:51:53 +01:00

10 KiB
Raw Permalink Blame History

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)

  • 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)

  • 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)

  • 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)

  • 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)

  • 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)

  • 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/)

  • 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)

  • 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)

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

cd backend
npm run migrate:tenant -- <tenant-slug>
npm run seed:demo-process -- <tenant-slug>

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)

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)

POST   /tenants/:tenantId/ai-processes/chat/messages
SSE    /tenants/:tenantId/ai-processes/stream?sessionId=xxx

Event Stream Types

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

cd backend
npm run migrate:tenant -- tenant1

2. Seed Demo Data

npm run seed:demo-process -- tenant1

3. Start Backend

npm run start:dev

4. Build Editor (if needed)

cd frontend/ai-processes-editor
npm install
npm run build

5. Start Frontend

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
  2. Add schema validation in ai-processes.schemas.ts
  3. Implement executor in ai-processes.runner.ts
  4. Add UI component in React Flow editor

Adding New Tools

  1. Implement handler in 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:

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