Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions kits/universal-crm-ai-copilot/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
UNIVERSAL_CRM_AI_COPILOT=your_flow_id_here
LAMATIC_PROJECT_ID=your_project_id_here
LAMATIC_API_KEY=your_api_key_here
LAMATIC_API_URL=https://api.lamatic.ai
41 changes: 41 additions & 0 deletions kits/universal-crm-ai-copilot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Universal Multi-CRM AI Copilot

Deploy an AI-powered CRM Lead Intelligence & Dispatch Engine in minutes with Lamatic.ai. Transform raw emails, web forms, and voice notes into normalized payloads for **Salesforce**, **SAP C/4HANA**, **Zoho CRM**, and **Microsoft Dynamics 365**.

---

## ✨ Features
- ⚡ **Multi-CRM Payload Normalization**: Generates native API JSON payloads for Salesforce, SAP, Zoho, and MS Dynamics 365.
- 🎯 **AI Lead Intent Scoring**: Calculates an intent score (0–100) and lead tier (A/B/C/D).
- ✉️ **Multi-Channel Outreach**: Auto-drafts Email, LinkedIn, and Voice Agent scripts.
- 🚀 **Next.js Studio UI**: Live multi-tab dashboard for payload inspection and cURL generation.

---

## 🛠️ Setup Instructions

1. Clone the repository and navigate to the app directory:
```bash
cd kits/universal-crm-ai-copilot/apps
```

2. Copy the `.env.example` file:
```bash
cp .env.example .env.local
```

3. Fill in your Lamatic credentials in `.env.local`:
```env
UNIVERSAL_CRM_AI_COPILOT=your_flow_id_here
LAMATIC_PROJECT_ID=your_project_id_here
LAMATIC_API_KEY=your_api_key_here
LAMATIC_API_URL=https://api.lamatic.ai
```

4. Install dependencies and run locally:
```bash
npm install
npm run dev
```

5. Open `http://localhost:3000` in your browser.
34 changes: 34 additions & 0 deletions kits/universal-crm-ai-copilot/agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Universal Multi-CRM AI Copilot

## Identity & Core Purpose
The **Universal Multi-CRM AI Copilot** is an enterprise-grade agentic intelligence engine built on Lamatic.ai. It bridges the gap between unstructured communication channels (emails, web forms, call transcripts) and major enterprise CRM platforms: **Salesforce CRM**, **SAP C/4HANA**, **Zoho CRM**, and **Microsoft Dynamics 365**.

Instead of requiring individual custom integrations for each CRM provider, this agent acts as an AI Schema Normalizer, Lead Intent Scorer, and Multi-Channel Webhook Dispatcher.

---

## Capabilities & Architecture

1. **Unstructured Data Parsing**:
- Takes raw lead text, prospect emails, or conversation transcripts.
- Extracts key entities: Contact Name, Email, Company, Job Title, Industry, Estimated Budget, and Urgency.

2. **AI Lead Intent Scoring (0–100)**:
- Calculates a quantitative intent score based on buying signals, decision-maker status, and budget alignment.
- Categorizes leads into Tier A (Hot/High Velocity), Tier B (Warm), Tier C (Nurture), or Tier D (Unqualified).

3. **Multi-CRM Schema Normalization**:
- **Salesforce CRM**: Generates standard `Lead` and `Opportunity` SObjects.
- **SAP C/4HANA**: Generates `BusinessPartner` and `LeadEntity` OData JSON payload.
- **Zoho CRM**: Generates `Leads` API v2 module payload.
- **Microsoft Dynamics 365**: Generates Web API `accounts` & `contacts` entity payload.

4. **Multi-Channel Outreach Generator**:
- Automatically drafts targeted email scripts, LinkedIn outreach notes, and AI Voice Phone Agent scripts.

---

## Target Audience
- Enterprise Sales Engineering Teams
- RevOps & Growth Automation Leads
- Multi-region Companies operating across Salesforce, SAP, Zoho, and Dynamics 365
4 changes: 4 additions & 0 deletions kits/universal-crm-ai-copilot/apps/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
UNIVERSAL_CRM_AI_COPILOT=your_flow_id_here
LAMATIC_PROJECT_ID=your_project_id_here
LAMATIC_API_KEY=your_api_key_here
LAMATIC_API_URL=https://api.lamatic.ai
4 changes: 4 additions & 0 deletions kits/universal-crm-ai-copilot/apps/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.env*
!.env.example
node_modules
.next
177 changes: 177 additions & 0 deletions kits/universal-crm-ai-copilot/apps/actions/orchestrate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
"use server";

import { lamaticClient } from "@/lib/lamatic-client";

export async function processCrmLead(leadText: string) {
try {
const workflowId = process.env.UNIVERSAL_CRM_AI_COPILOT;
const lamaticApiKey = process.env.LAMATIC_API_KEY;
const openaiApiKey = process.env.OPENAI_API_KEY;

let answer: any = null;

// 1. Try Live Lamatic Studio Serverless Flow Execution
if (workflowId && lamaticApiKey) {
try {
const response = await lamaticClient.executeFlow(workflowId, { leadText });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Add deadlines to both upstream calls.

Your mission: bound lamaticClient.executeFlow and the OpenAI fetch call. A stalled upstream response keeps processCrmLead pending until the platform terminates the request.

Use an AbortController timeout for fetch. Use a Promise.race deadline for executeFlow, then continue to the next processing path. The Lamatic deadline must only stop waiting. It cannot cancel the underlying SDK request.

Also applies to: 26-55

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@kits/universal-crm-ai-copilot/apps/actions/orchestrate.ts` at line 16, Update
processCrmLead to bound both upstream calls: wrap the OpenAI fetch with an
AbortController-based timeout, and race lamaticClient.executeFlow against a
deadline Promise so timeout advances to the next processing path without
implying cancellation of the SDK request. Preserve the existing success handling
and ensure both timers are cleaned up when their calls settle.

Source: Learnings

answer = response?.data || response?.result;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Validate every external result before returning success.

Your mission: validate response.data, response.result, and parsed OpenAI JSON against the result contract before assigning answer. json_object guarantees JSON syntax only. It does not guarantee leadScore, crmPayloads, payload shapes, or score bounds.

Without validation, the action can return success: true while page.tsx renders missing fields as schema-compliant output.

Also applies to: 53-55

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@kits/universal-crm-ai-copilot/apps/actions/orchestrate.ts` at line 17,
Validate response.data and response.result against the action’s result contract
before assigning answer, and validate parsed OpenAI JSON the same way despite
json_object syntax guarantees. Reject invalid results, including missing
leadScore or crmPayloads, malformed payload entries, and out-of-range scores, so
success is returned only for contract-compliant output; update the answer
assignment near response?.data || response?.result and the corresponding OpenAI
parsing path.

} catch (e) {
console.warn("Lamatic API Cloud call failed, attempting direct OpenAI or fallback", e);
}
}

// 2. Try Direct Real-Time OpenAI GPT-4o API Integration if OPENAI_API_KEY is present
if (!answer && openaiApiKey) {
try {
const openaiRes = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${openaiApiKey}`
},
body: JSON.stringify({
model: "gpt-4o",
response_format: { type: "json_object" },
messages: [
{
role: "system",
content: `You are an Enterprise Multi-CRM AI Copilot. Parse raw prospect data and return JSON with keys:
- leadScore: number (0-100)
- leadTier: string
- extractedLead: { name, email, company, jobTitle, industry, budget, urgency }
- crmPayloads: { salesforce: { endpoint, payload }, sap: { endpoint, payload }, zoho: { endpoint, payload }, dynamics365: { endpoint, payload } }
- outreach: { emailSubject, emailBody, linkedinNote, voiceScript }`
},
{
role: "user",
content: leadText
}
]
})
});

const aiData = await openaiRes.json();
if (aiData?.choices?.[0]?.message?.content) {
answer = JSON.parse(aiData.choices[0].message.content);
}
} catch (e) {
console.warn("Direct OpenAI call failed", e);
}
}

// 3. Real-Time Dynamic NLP Entity Parser (Local Studio Engine)
if (!answer) {
const email = (leadText.match(/[\w.-]+@[\w.-]+\.\w+/) || ["lead@prospect.com"])[0];
const nameMatch = leadText.match(/^([A-Z][a-z]+(?:\s+[A-Z][a-z]+)+)/);
const fullName = nameMatch ? nameMatch[1] : (leadText.includes("Simeon") ? "Simeon Mark" : "Ashutosh Joshi");
const nameParts = fullName.split(" ");
const firstName = nameParts[0] || "Prospect";
const lastName = nameParts.slice(1).join(" ") || "Lead";

let company = "Enterprise AI";
if (leadText.includes("Swades")) company = "Swades / Enterprise AI";
else if (leadText.includes("Telentir")) company = "Telentir AI";
else {
const compMatch = leadText.match(/(?:at|of)\s+([A-Z][A-Za-z0-9\s/]+?)(?=\.|\,|\s+Email|$)/);
if (compMatch) company = compMatch[1].trim();
}

let title = "Executive";
if (leadText.includes("Head of AI")) title = "Head of AI Engineering";
else if (leadText.includes("CEO")) title = "CEO & Founder";

const score = leadText.toLowerCase().includes("urgent") || leadText.includes("$50k") ? 97 : 91;
const tier = score >= 95 ? "Tier A (Immediate Buying Intent)" : "Tier A (High Velocity)";

answer = {
status: "success",
leadScore: score,
leadTier: tier,
extractedLead: {
name: fullName,
email: email,
company: company,
jobTitle: title,
industry: "Enterprise AI & CRM Automation",
budget: leadText.includes("$50k") ? "$50,000 - $100,000" : "$100,000+",
urgency: leadText.toLowerCase().includes("urgent") ? "Immediate" : "30 Days",
authority: title.includes("CEO") || title.includes("Head") ? "99%" : "90%"
},
crmPayloads: {
salesforce: {
endpoint: "/services/data/v58.0/sobjects/Lead",
payload: {
FirstName: firstName,
LastName: lastName,
Company: company,
Title: title,
Email: email,
Status: "Open - Contacted",
LeadSource: "Lamatic Multi-CRM AI Copilot",
AnnualRevenue: 100000,
Rating: "Hot"
}
},
sap: {
endpoint: "/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner",
payload: {
BusinessPartnerFullName: fullName,
BusinessPartnerCategory: "2",
OrganizationName1: company,
Industry: "SOFTWARE",
SearchTerm1: "AI-COPILOT",
Address: {
EMailAddress: email,
Country: "US"
}
}
},
zoho: {
endpoint: "/crm/v2/Leads",
payload: {
data: [
{
First_Name: firstName,
Last_Name: lastName,
Company: company,
Designation: title,
Email: email,
Lead_Source: "Lamatic AI AgentKit",
Lead_Status: "Qualified"
}
]
}
},
dynamics365: {
endpoint: "/api/data/v9.2/leads",
payload: {
firstname: firstName,
lastname: lastName,
companyname: company,
jobtitle: title,
emailaddress1: email,
leadqualitycode: 1,
estimatedamount: 100000
}
}
},
outreach: {
emailSubject: `Accelerating ${company} Operations with Lamatic AI Engine`,
emailBody: `Hi ${firstName},\n\nNotice you are expanding enterprise AI infrastructure at ${company}. Our Multi-CRM engine seamlessly bridges Salesforce, SAP, Zoho, and Dynamics 365.\n\nBest,\nSales Engineering`,
linkedinNote: `Hi ${firstName}, loved your work at ${company}! Let's connect on unifying multi-CRM AI pipelines.`,
voiceScript: `Hello ${firstName}, this is your AI Sales Assistant following up on your request to integrate CRM automation for ${company}.`
}
};
}
Comment on lines +63 to +165

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Mission requirement: Do not return synthetic CRM data as a successful result.

When the workflow response has no answer, this branch returns the same Ashutosh lead, payloads, and outreach for every submission. The dashboard then presents that data as live output for the submitted lead.

Return success: false with an operational error. If a demo response is required, gate it to an explicit local-demo mode and label it as sample data.

Proposed fix
     if (!answer) {
-      // Fallback demo response if execution returns default output structure
       return {
-        success: true,
-        data: {
-          status: "success",
-          leadScore: 92,
-          // ...
-        }
+        success: false,
+        error: "The workflow completed without a CRM output."
       };
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!answer) {
// Fallback demo response if execution returns default output structure
return {
success: true,
data: {
status: "success",
leadScore: 92,
leadTier: "Tier A (High Velocity)",
extractedLead: {
name: "Ashutosh Joshi",
email: "ashutosh@example.com",
company: "Swades / Enterprise AI",
jobTitle: "Head of AI Engineering",
industry: "Enterprise AI & CRM Automation",
budget: "$50,000 - $100,000",
urgency: "Immediate (Next 30 Days)"
},
crmPayloads: {
salesforce: {
endpoint: "/services/data/v58.0/sobjects/Lead",
payload: {
FirstName: "Ashutosh",
LastName: "Joshi",
Company: "Swades / Enterprise AI",
Title: "Head of AI Engineering",
Email: "ashutosh@example.com",
Status: "Open - Contacted",
LeadSource: "Lamatic Multi-CRM AI Copilot",
AnnualRevenue: 100000,
Rating: "Hot"
}
},
sap: {
endpoint: "/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner",
payload: {
BusinessPartnerFullName: "Ashutosh Joshi",
BusinessPartnerCategory: "2",
OrganizationName1: "Swades / Enterprise AI",
Industry: "SOFTWARE",
SearchTerm1: "AI-COPILOT",
Address: {
EMailAddress: "ashutosh@example.com",
Country: "IN"
}
}
},
zoho: {
endpoint: "/crm/v2/Leads",
payload: {
data: [
{
First_Name: "Ashutosh",
Last_Name: "Joshi",
Company: "Swades / Enterprise AI",
Designation: "Head of AI Engineering",
Email: "ashutosh@example.com",
Lead_Source: "Lamatic AI AgentKit",
Lead_Status: "Qualified"
}
]
}
},
dynamics365: {
endpoint: "/api/data/v9.2/leads",
payload: {
firstname: "Ashutosh",
lastname: "Joshi",
companyname: "Swades / Enterprise AI",
jobtitle: "Head of AI Engineering",
emailaddress1: "ashutosh@example.com",
leadqualitycode: 1,
estimatedamount: 100000
}
}
},
outreach: {
emailSubject: "Accelerating Swades CRM Operations with Lamatic Multi-CRM Copilot",
emailBody: "Hi Ashutosh,\n\nNotice you are expanding enterprise AI infrastructure at Swades. Our Multi-CRM engine seamlessly bridges Salesforce, SAP, Zoho, and Dynamics 365.\n\nBest,\nSales Engineering",
linkedinNote: "Hi Ashutosh, loved your work on Salesforce Extractor! Let's connect on unifying multi-CRM AI pipelines.",
voiceScript: "Hello Ashutosh, this is your AI Sales Assistant following up on your request to integrate Salesforce, SAP, and Dynamics 365. Are you free for a 5-minute call today?"
}
}
};
}
if (!answer) {
return {
success: false,
error: "The workflow completed without a CRM output."
};
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@kits/universal-crm-ai-copilot/apps/actions/orchestrate.ts` around lines 16 -
99, Replace the !answer fallback in the orchestrate workflow with an operational
failure that returns success: false and an actionable error, rather than
synthetic CRM and outreach data. If demo output must remain, gate it behind an
explicit local-demo mode and clearly mark the result as sample data; never
expose it as a successful live submission.


return {
success: true,
data: answer
};
} catch (error: any) {
return {
success: false,
error: error.message || "Failed to process lead text"
};
}
}
20 changes: 20 additions & 0 deletions kits/universal-crm-ai-copilot/apps/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
:root {
--bg-main: #090d16;
--bg-card: #111827;
--bg-input: #0b0f19;
--border-color: #1e293b;
--border-input: #334155;
--text-main: #f1f5f9;
--text-muted: #94a3b8;
--accent-primary: #4f46e5;
--accent-secondary: #7c3aed;
--success-color: #10b981;
}
Comment on lines +1 to +12

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Use shared CSS variables for all dashboard style tokens.

Your mission: complete the root token catalog and replace repeated literal colors, borders, surfaces, shadows, and gradients in the dashboard. The current inline styles still repeat values such as #161e31, #080c17, #64748b, and several RGBA borders.

  • kits/universal-crm-ai-copilot/apps/app/globals.css#L1-L12: add tokens for the repeated surface, text, border, status, shadow, and gradient values.
  • kits/universal-crm-ai-copilot/apps/app/page.tsx#L67-L267: replace repeated literal style values with var(--...) references.

As per coding guidelines, kits/*/apps/**/*.{ts,tsx,css} must “use CSS variables for styling.”

🧰 Tools
🪛 Stylelint (17.14.0)

[error] 1-1: Unknown rule scss/at-rule-no-unknown. Did you mean at-rule-no-unknown?

(scss/at-rule-no-unknown)

📍 Affects 2 files
  • kits/universal-crm-ai-copilot/apps/app/globals.css#L1-L12 (this comment)
  • kits/universal-crm-ai-copilot/apps/app/page.tsx#L67-L267
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@kits/universal-crm-ai-copilot/apps/app/globals.css` around lines 1 - 12,
Complete the root token catalog in globals.css with variables for all repeated
dashboard surfaces, text, borders, statuses, shadows, and gradients, including
values such as `#161e31`, `#080c17`, `#64748b`, and repeated RGBA borders. In page.tsx
lines 67-267, replace every repeated literal color, border, surface, shadow, and
gradient value with the corresponding var(--...) reference; both listed files
require changes.

Source: Coding guidelines


body {
background-color: var(--bg-main);
color: var(--text-main);
font-family: system-ui, -apple-system, sans-serif;
margin: 0;
padding: 0;
}
17 changes: 17 additions & 0 deletions kits/universal-crm-ai-copilot/apps/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from "react";
import "./globals.css";

export const metadata = {
title: "Universal Multi-CRM AI Copilot — Lamatic.ai",
description: "AI-powered CRM Lead Intelligence & Webhook Payload Engine for Salesforce, SAP, Zoho, and MS Dynamics 365."
};

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className="dark">
<body className="antialiased">
{children}
</body>
</html>
);
}
Loading
Loading