Skip to content

feat: Add universal-crm-ai-copilot kit - #332

Open
ashutoshjoshi23 wants to merge 12 commits into
Lamatic:mainfrom
ashutoshjoshi23:feat/add-universal-crm-ai-copilot
Open

feat: Add universal-crm-ai-copilot kit#332
ashutoshjoshi23 wants to merge 12 commits into
Lamatic:mainfrom
ashutoshjoshi23:feat/add-universal-crm-ai-copilot

Conversation

@ashutoshjoshi23

@ashutoshjoshi23 ashutoshjoshi23 commented Aug 7, 2026

Copy link
Copy Markdown

Add universal-crm-ai-copilot Kit

Summary

The universal-crm-ai-copilot is an enterprise-grade AI intelligence engine built for the Lamatic.ai platform. It bridges unstructured communication data (such as prospect emails, web forms, and voice transcripts) with enterprise CRM systems by normalizing data into native API payloads for Salesforce CRM, SAP C/4HANA, Zoho CRM, and Microsoft Dynamics 365. Additionally, the kit provides AI Lead Intent Scoring (0–100) and automated multi-channel outreach generation.

Key Capabilities

  • Multi-CRM Schema Normalization: Parses unstructured inputs into official REST/OData API payloads for Salesforce, SAP C/4HANA, Zoho CRM, and MS Dynamics 365.
  • AI Lead Intent Scoring: Evaluates lead velocity, decision-maker authority, and budget alignment to calculate a quantitative intent score (0–100) and assign lead tiers (Tier A/B/C/D).
  • Multi-Channel Outreach Engine: Generates targeted email follow-ups, LinkedIn connection notes, and AI Voice Phone Agent scripts.
  • Next.js Studio UI: Provides an interactive multi-tab dashboard (apps/) for inspecting payloads and generating cURL commands.

PR Compliance Checklist

  • Placed directly under kits/universal-crm-ai-copilot/
  • Includes valid lamatic.config.ts configured with type: "kit"
  • Externalized prompts, model configs, constitutions, and scripts referenced via @references in flows/universal-crm-ai-copilot.ts
  • No environment variables or credentials committed (only .env.example)
  • Adds the universal-crm-ai-copilot kit under kits/universal-crm-ai-copilot/.
  • Adds documentation for supported CRM platforms, lead scoring, outreach generation, setup, and local development.
  • Adds kit metadata, environment templates, Lamatic configuration, and a constitution with PII-safe logging and fallback field rules.
  • Adds externalized CRM prompts and a gpt-4o model configuration.
  • Adds a CRM flow that receives raw lead text, processes it with an LLM, finalizes the structured result, and returns the response through sequential nodes.
  • Adds the processCrmLead server action with Lamatic execution, direct OpenAI generation, and local fallback parsing.
  • Adds a Next.js Studio application with lead input, sample leads, intent scoring, extracted entities, CRM payload views, JSON and cURL modes, clipboard copying, loading states, and error handling.
  • Adds Salesforce, SAP C/4HANA, Zoho CRM, and Microsoft Dynamics 365 payload generation.
  • Adds email, LinkedIn, and AI voice-agent outreach generation.
  • Adds a standalone dark-themed dashboard preview with CRM switching, payload inspection, cURL support, and real-time lead processing.
  • Adds a Python generator and test for CRM payloads, exact intent-score and tier assertions, endpoints, and outreach content.
  • Adds Next.js, React, TypeScript, Lamatic, and environment-file configuration.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1bec1c35-42af-48eb-afd1-83b88dae9b68

📥 Commits

Reviewing files that changed from the base of the PR and between 0fcab5f and 0dfcd73.

📒 Files selected for processing (1)
  • kits/universal-crm-ai-copilot/test_crm_payloads.py

Walkthrough

The kit adds a Lamatic Universal Multi-CRM AI Copilot flow, a Next.js dashboard, a standalone dashboard preview, CRM payload validation, and setup documentation.

Changes

Universal CRM AI Copilot

Layer / File(s) Summary
CRM flow and processing contracts
kits/universal-crm-ai-copilot/constitutions/default.md, kits/universal-crm-ai-copilot/flows/..., kits/universal-crm-ai-copilot/model-configs/..., kits/universal-crm-ai-copilot/prompts/..., kits/universal-crm-ai-copilot/lamatic.config.ts
Defines CRM schema rules, lead-processing prompts, the gpt-4o configuration, Lamatic flow nodes and edges, and kit metadata.
Workflow execution and fallback processing
kits/universal-crm-ai-copilot/apps/actions/orchestrate.ts, kits/universal-crm-ai-copilot/apps/lib/lamatic-client.ts, kits/universal-crm-ai-copilot/apps/orchestrate.js, kits/universal-crm-ai-copilot/.env.example, kits/universal-crm-ai-copilot/apps/.env.example
Configures Lamatic access, executes lead processing through Lamatic or OpenAI, applies local parsing fallback, and returns structured results or errors.
Next.js dashboard experience
kits/universal-crm-ai-copilot/apps/app/...
Adds lead submission, intent metrics, CRM selection, JSON and cURL views, copy actions, and outreach output.
Preview, validation, and operating setup
kits/universal-crm-ai-copilot/dashboard_preview.html, kits/universal-crm-ai-copilot/test_crm_payloads.py, kits/universal-crm-ai-copilot/README.md, kits/universal-crm-ai-copilot/agent.md, kits/universal-crm-ai-copilot/apps/package.json, kits/universal-crm-ai-copilot/apps/tsconfig.json, kits/universal-crm-ai-copilot/apps/next.config.mjs, kits/universal-crm-ai-copilot/apps/.gitignore
Adds the standalone dashboard preview, sample CRM payload output, supported-platform documentation, environment setup, package scripts, TypeScript settings, Next.js configuration, and ignored local files.

Suggested reviewers: amanintech, d-pamneja

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary change: adding the universal CRM AI copilot kit.
Description check ✅ Passed The description provides the kit purpose, capabilities, location, configuration details, external references, and credential handling.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

:robot_face: AgentKit Structural Validation

New Contributions Detected

  • Kit: kits/universal-crm-ai-copilot

Check Results

Check Status
No edits to existing kits ✅ Pass
Required root files present ✅ Pass
Flow .ts files present ✅ Pass
lamatic.config.ts valid ✅ Pass
No changes outside kits/ ✅ Pass

🎉 All checks passed! This contribution follows the AgentKit structure.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 10

🤖 Prompt for all review comments with 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.

Inline comments:
In `@kits/universal-crm-ai-copilot/apps/.gitignore`:
- Around line 1-2: Update the ignore rules in .gitignore to ignore all
environment-file variants using a wildcard pattern, then explicitly re-include
.env.example so the template remains tracked.

In `@kits/universal-crm-ai-copilot/apps/actions/orchestrate.ts`:
- Around line 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.

In `@kits/universal-crm-ai-copilot/apps/app/page.tsx`:
- Around line 28-34: Update handleCopy so it awaits
navigator.clipboard.writeText before calling setCopied(true) or starting the
reset timeout; handle rejected writes without changing copied, while preserving
the activePayload guard.
- Around line 16-24: Update handleSubmit to wrap processCrmLead in try/finally
so setLoading(false) always executes, including when the action rejects. Add
state for an error message, populate it from res.error when success is false,
and render that message; preserve the existing successful result handling.
- Around line 37-177: Replace the repeated color, background, border, and
related style literals throughout the page JSX with named CSS variables,
defining the tokens in the page’s stylesheet or root styling scope and
referencing them via var(--token-name). Update the inline style objects in the
main layout and panels, buttons, tabs, payload viewer, and outreach preview
while preserving the current visual values and behavior.

In `@kits/universal-crm-ai-copilot/apps/orchestrate.js`:
- Around line 1-12: Remove the parent-kit lamatic.config.ts import from the
app-local configuration in orchestrate.js, define the flow name directly within
this module, and preserve the existing UNIVERSAL_CRM_AI_COPILOT workflowId
mapping so it remains aligned with the parent kit step.

In `@kits/universal-crm-ai-copilot/apps/package.json`:
- Line 12: Replace the floating "latest" version in the package manifest with
the exact tested Lamatic SDK version, then regenerate and commit the app
lockfile using that pinned dependency. Verify the resulting dependency tree with
a clean install and confirm the production build succeeds.
- Around line 14-16: Update the package manifest dependencies for next, react,
react-dom, `@types/react`, and `@types/react-dom` to the kit-supported stack:
Next.js 14–15 and React 18 with matching type packages. Regenerate the lockfile,
perform a clean install, and verify the production build succeeds.

In `@kits/universal-crm-ai-copilot/apps/tsconfig.json`:
- Line 7: Enable strict TypeScript checking by changing the strict compiler
option in the app configuration to true, then resolve all resulting type errors
across the application, particularly around CRM payload nullability and
implicit-any values; only retain an exception if it is explicitly documented in
the configuration.

In `@kits/universal-crm-ai-copilot/README.md`:
- Line 31: Remove the exposed LAMATIC_API_KEY value from the README and replace
it with an unmistakable placeholder such as your_api_key_here. Revoke or rotate
the compromised credential, purge it from repository history, and keep the real
value only in the local environment configuration.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1604e21c-bae8-433d-82cf-cb8781a26be2

📥 Commits

Reviewing files that changed from the base of the PR and between fd6104d and 839f4ae.

📒 Files selected for processing (19)
  • kits/universal-crm-ai-copilot/.env.example
  • kits/universal-crm-ai-copilot/README.md
  • kits/universal-crm-ai-copilot/agent.md
  • kits/universal-crm-ai-copilot/apps/.env.example
  • kits/universal-crm-ai-copilot/apps/.gitignore
  • kits/universal-crm-ai-copilot/apps/actions/orchestrate.ts
  • kits/universal-crm-ai-copilot/apps/app/layout.tsx
  • kits/universal-crm-ai-copilot/apps/app/page.tsx
  • kits/universal-crm-ai-copilot/apps/lib/lamatic-client.ts
  • kits/universal-crm-ai-copilot/apps/next.config.mjs
  • kits/universal-crm-ai-copilot/apps/orchestrate.js
  • kits/universal-crm-ai-copilot/apps/package.json
  • kits/universal-crm-ai-copilot/apps/tsconfig.json
  • kits/universal-crm-ai-copilot/constitutions/default.md
  • kits/universal-crm-ai-copilot/flows/universal-crm-ai-copilot.ts
  • kits/universal-crm-ai-copilot/lamatic.config.ts
  • kits/universal-crm-ai-copilot/model-configs/crm-llm.ts
  • kits/universal-crm-ai-copilot/prompts/crm-system.md
  • kits/universal-crm-ai-copilot/prompts/crm-user.md

Comment thread kits/universal-crm-ai-copilot/apps/.gitignore Outdated
Comment on lines +16 to +99
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?"
}
}
};
}

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.

Comment thread kits/universal-crm-ai-copilot/apps/app/page.tsx
Comment thread kits/universal-crm-ai-copilot/apps/app/page.tsx Outdated
Comment thread kits/universal-crm-ai-copilot/apps/app/page.tsx Outdated
Comment thread kits/universal-crm-ai-copilot/apps/orchestrate.js Outdated
Comment thread kits/universal-crm-ai-copilot/apps/package.json Outdated
Comment thread kits/universal-crm-ai-copilot/apps/package.json Outdated
Comment thread kits/universal-crm-ai-copilot/apps/tsconfig.json Outdated
Comment thread kits/universal-crm-ai-copilot/README.md Outdated

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 8

♻️ Duplicate comments (1)
kits/universal-crm-ai-copilot/apps/actions/orchestrate.ts (1)

64-69: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Reject incomplete leads instead of inventing identity data.

Your mission: do not substitute "lead@prospect.com", "Ashutosh Joshi", or other default identity values when parsing fails. A successful response can then produce a CRM payload for a person who was not present in leadText.

If required identity fields are unavailable, return an actionable failure or mark the result as explicit sample data.

🤖 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 64 -
69, Update the lead identity parsing in the orchestration flow around email,
fullName, firstName, and lastName so parsing failures do not fall back to
invented identities such as lead@prospect.com, Simeon Mark, Ashutosh Joshi,
Prospect, or Lead. Validate that required identity fields were extracted from
leadText and return an actionable failure, or explicitly mark the output as
sample data, before constructing the CRM payload.
🤖 Prompt for all review comments with 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.

Inline comments:
In `@kits/universal-crm-ai-copilot/apps/actions/orchestrate.ts`:
- 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.
- 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.

In `@kits/universal-crm-ai-copilot/apps/app/globals.css`:
- Around line 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.

In `@kits/universal-crm-ai-copilot/apps/app/page.tsx`:
- Line 191: Update the progress-bar width expression in the lead score render to
use a nullish fallback instead of `||`, preserving a valid `result.leadScore` of
0; clamp the resulting score to the inclusive 0–100 range before appending the
percentage.
- Line 47: Update the command-generation logic containing
JSON.stringify(activePayload.payload) to escape single quotes using
POSIX-shell-safe quoting before placing the result inside the -d '...' argument.
Preserve the existing curl command structure while ensuring apostrophes in
lead-derived or model-generated payload values cannot terminate the shell
string.

In `@kits/universal-crm-ai-copilot/dashboard_preview.html`:
- Around line 566-577: Align the preview scoring logic in the text-processing
block with the application contract used by orchestrate.ts, especially for
inputs containing “$50k,” so both implementations return the same score and
tier. Alternatively, explicitly mark this page as static mock output if it is
not intended to reflect live application behavior.
- Around line 693-696: Update copyViewer so it waits for
navigator.clipboard.writeText to resolve before showing the success alert, and
handle rejected writes without leaving an unhandled promise. Preserve the
existing copied-content source and success message, while reporting failure
through the page’s established error-handling mechanism if available.

In `@kits/universal-crm-ai-copilot/test_crm_payloads.py`:
- Around line 7-105: Convert test_universal_crm_copilot from a print-only
fixture into an executable contract test by extracting the fallback payload
construction into a callable function and invoking the lead-processing
implementation. Add assertions covering each CRM’s required endpoint and payload
fields, including Salesforce, SAP, Zoho, and Dynamics 365, while preserving the
expected outreach and lead data as needed. Only print the success message after
all validations have passed.

---

Duplicate comments:
In `@kits/universal-crm-ai-copilot/apps/actions/orchestrate.ts`:
- Around line 64-69: Update the lead identity parsing in the orchestration flow
around email, fullName, firstName, and lastName so parsing failures do not fall
back to invented identities such as lead@prospect.com, Simeon Mark, Ashutosh
Joshi, Prospect, or Lead. Validate that required identity fields were extracted
from leadText and return an actionable failure, or explicitly mark the output as
sample data, before constructing the CRM payload.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 502f19dd-a3db-45c1-80e8-09d1f9195a6a

📥 Commits

Reviewing files that changed from the base of the PR and between 839f4ae and 3053111.

📒 Files selected for processing (11)
  • kits/universal-crm-ai-copilot/README.md
  • kits/universal-crm-ai-copilot/apps/.gitignore
  • kits/universal-crm-ai-copilot/apps/actions/orchestrate.ts
  • kits/universal-crm-ai-copilot/apps/app/globals.css
  • kits/universal-crm-ai-copilot/apps/app/layout.tsx
  • kits/universal-crm-ai-copilot/apps/app/page.tsx
  • kits/universal-crm-ai-copilot/apps/orchestrate.js
  • kits/universal-crm-ai-copilot/apps/package.json
  • kits/universal-crm-ai-copilot/apps/tsconfig.json
  • kits/universal-crm-ai-copilot/dashboard_preview.html
  • kits/universal-crm-ai-copilot/test_crm_payloads.py

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

if (workflowId && lamaticApiKey) {
try {
const response = await lamaticClient.executeFlow(workflowId, { leadText });
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.

Comment on lines +1 to +12
: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;
}

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

Comment thread kits/universal-crm-ai-copilot/apps/app/page.tsx Outdated
</div>
</div>
<div style={{ width: "100%", height: "10px", background: "rgba(15, 23, 42, 0.8)", borderRadius: "9999px", overflow: "hidden" }}>
<div style={{ height: "100%", width: `${result.leadScore || 95}%`, background: "linear-gradient(90deg, #10b981 0%, #34d399 100%)", borderRadius: "9999px" }} />

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Render a zero score as zero.

Your mission: replace result.leadScore || 95 with a nullish fallback and clamp the width to 0 through 100. A valid score of 0 currently renders a 95% progress bar.

Proposed fix
-                  <div style={{ height: "100%", width: `${result.leadScore || 95}%`, background: "linear-gradient(90deg, `#10b981` 0%, `#34d399` 100%)", borderRadius: "9999px" }} />
+                  <div style={{ height: "100%", width: `${Math.min(100, Math.max(0, result.leadScore ?? 0))}%`, background: "linear-gradient(90deg, `#10b981` 0%, `#34d399` 100%)", borderRadius: "9999px" }} />
📝 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
<div style={{ height: "100%", width: `${result.leadScore || 95}%`, background: "linear-gradient(90deg, #10b981 0%, #34d399 100%)", borderRadius: "9999px" }} />
<div style={{ height: "100%", width: `${Math.min(100, Math.max(0, result.leadScore ?? 0))}%`, background: "linear-gradient(90deg, `#10b981` 0%, `#34d399` 100%)", borderRadius: "9999px" }} />
🤖 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/page.tsx` at line 191, Update the
progress-bar width expression in the lead score render to use a nullish fallback
instead of `||`, preserving a valid `result.leadScore` of 0; clamp the resulting
score to the inclusive 0–100 range before appending the percentage.

Comment on lines +566 to +577
let score = 95;
let tier = "Tier A (High Velocity)";
let authority = "98%";
let budget = "$100k+";
let urgency = "30 Days";

if (text.toLowerCase().includes("urgent")) {
score = 97;
tier = "Tier A (Immediate Buying Intent)";
urgency = "Immediate";
authority = "99%";
}

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: Align preview scoring with the application contract.

The documented $50k-$100k sample returns 95 and Tier A (High Velocity) here. kits/universal-crm-ai-copilot/apps/actions/orchestrate.ts assigns 97 and Tier A (Immediate Buying Intent) when the input contains $50k. The preview can show a different lead priority than the Next.js dashboard.

Use the same scoring rule in both implementations, or mark this page as static mock 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/dashboard_preview.html` around lines 566 - 577,
Align the preview scoring logic in the text-processing block with the
application contract used by orchestrate.ts, especially for inputs containing
“$50k,” so both implementations return the same score and tier. Alternatively,
explicitly mark this page as static mock output if it is not intended to reflect
live application behavior.

Comment thread kits/universal-crm-ai-copilot/dashboard_preview.html Outdated
Comment thread kits/universal-crm-ai-copilot/test_crm_payloads.py Outdated

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
kits/universal-crm-ai-copilot/test_crm_payloads.py (1)

17-107: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Mission: Test the production CRM contract, not a local fixture.

output is constructed in this test and never calls the lead-processing implementation. The assertions can pass when processCrmLead is broken.

The fixture already differs from kits/universal-crm-ai-copilot/apps/actions/orchestrate.ts: this $50k-$100k input produces 97 and Tier A (Immediate Buying Intent) there, but lines 19-20 expect 95 and Tier A (High Velocity).

Extract the fallback generator into a shared testable module, or add an integration test that invokes processCrmLead. Assert each endpoint and required payload field from its actual response.

#!/bin/bash
set -euo pipefail

# Inspect the production response contract and the current test fixture.
sed -n '1,220p' kits/universal-crm-ai-copilot/apps/actions/orchestrate.ts
sed -n '1,150p' kits/universal-crm-ai-copilot/test_crm_payloads.py

# Locate existing TypeScript test tooling before selecting the integration-test location.
fd -HI '^(package\.json|vitest\.config\..*|jest\.config\..*)$' kits/universal-crm-ai-copilot
🤖 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/test_crm_payloads.py` around lines 17 - 107,
Replace the locally constructed output fixture in the test with an invocation of
the production processCrmLead flow from orchestrate.ts, or extract its fallback
generator into a shared testable module and call that implementation. Update
expectations to match the actual response, including the production score and
tier, and assert every CRM endpoint plus each required payload field from the
returned result rather than from duplicated fixture data.
🤖 Prompt for all review comments with 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.

Inline comments:
In `@kits/universal-crm-ai-copilot/test_crm_payloads.py`:
- Line 98: In the score validation assertion, split the combined leadScore range
check into separate assertions for the lower bound and upper bound, preserving
the inclusive 0–100 range and providing distinct failure messages for each
violation.

---

Outside diff comments:
In `@kits/universal-crm-ai-copilot/test_crm_payloads.py`:
- Around line 17-107: Replace the locally constructed output fixture in the test
with an invocation of the production processCrmLead flow from orchestrate.ts, or
extract its fallback generator into a shared testable module and call that
implementation. Update expectations to match the actual response, including the
production score and tier, and assert every CRM endpoint plus each required
payload field from the returned result rather than from duplicated fixture data.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: db15e00b-0d6e-40d8-889a-5fc7b5776ad4

📥 Commits

Reviewing files that changed from the base of the PR and between 3053111 and a87dd35.

📒 Files selected for processing (3)
  • kits/universal-crm-ai-copilot/apps/app/page.tsx
  • kits/universal-crm-ai-copilot/dashboard_preview.html
  • kits/universal-crm-ai-copilot/test_crm_payloads.py

Comment thread kits/universal-crm-ai-copilot/test_crm_payloads.py Outdated
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🤖 Prompt for all review comments with 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.

Inline comments:
In `@kits/universal-crm-ai-copilot/test_crm_payloads.py`:
- Around line 4-7: Replace the Python-based contract test around
generate_crm_payloads with tests targeting the application fallback generator in
orchestrate.ts. Extract the runtime payload-generation logic into an exported
TypeScript symbol, then invoke that export through the project’s application
test tooling and cover the existing payload expectations; do not treat the
Python reimplementation as the runtime contract.
- Around line 129-131: Update the assertions in the generate_crm_payloads test
to retain the existing 0–100 leadScore range checks while also asserting the
deterministic fixture produces leadScore 97 and tier "Tier A (Immediate Buying
Intent)".
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 77a1d9d1-9166-4d82-9a98-42062893567c

📥 Commits

Reviewing files that changed from the base of the PR and between a87dd35 and 0fcab5f.

📒 Files selected for processing (1)
  • kits/universal-crm-ai-copilot/test_crm_payloads.py

Comment on lines +4 to +7
def generate_crm_payloads(lead_text: str) -> dict:
"""
Dynamic CRM Payload Generator & NLP Entity Extractor
Mirrors the contract defined in orchestrate.ts for multi-CRM payload construction.

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

Mission: Test the runtime payload generator.

Line 126 tests a Python reimplementation. The application serves a separate fallback implementation in kits/universal-crm-ai-copilot/apps/actions/orchestrate.ts at Lines 49-177. A payload change in that runtime path can pass this test.

Extract and export the TypeScript fallback generator. Test that exported generator with the application test tooling. Do not use this Python copy as the runtime contract test.

Also applies to: 125-126

🤖 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/test_crm_payloads.py` around lines 4 - 7,
Replace the Python-based contract test around generate_crm_payloads with tests
targeting the application fallback generator in orchestrate.ts. Extract the
runtime payload-generation logic into an exported TypeScript symbol, then invoke
that export through the project’s application test tooling and cover the
existing payload expectations; do not treat the Python reimplementation as the
runtime contract.

Comment thread kits/universal-crm-ai-copilot/test_crm_payloads.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant