feat: Meeting Intelligence Agent — Transform messy notes into action items#149
feat: Meeting Intelligence Agent — Transform messy notes into action items#149AnuragDubey007 wants to merge 22 commits intoLamatic:old-mainfrom
Conversation
Added README.md for Meeting Intelligence Agent with detailed information on features, setup, and usage.
Added configuration for Meeting Intelligence Agent with details on features, integrations, and author information.
PR Validation ResultsNew Contributions Detected
Check Results
🎉 All checks passed! This contribution follows the AgentKit structure. |
|
Important Review skippedAuto reviews are limited based on label configuration. 🏷️ Required labels (at least one) (1)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI (base), Organization UI (inherited) Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughThis mission introduces the Meeting Intelligence Agent kit—a complete Next.js application integrated with Lamatic workflows. The system extracts action items, decisions, and summaries from meeting notes via LLM processing, formats results into HTML emails, and delivers them via SMTP. Core infrastructure, API handlers, UI components, and Lamatic flow configurations are all established. Changes
Suggested reviewers
This message will self-destruct in 5 seconds. Your assignment: review this Meeting Intelligence Agent kit implementation for correctness of Lamatic API integration, Next.js configuration, flow logic, and UI completeness. Good luck. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
@coderabbitai review |
|
This message will self-destruct in five seconds... just kidding. Initiating a full review of PR
Good luck. The Agency is watching. 🕵️ 🧠 Learnings used✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 18
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@kits/automation/meeting-intelligence/actions/orchestrate.ts`:
- Around line 3-36: analyzeMeeting contains duplicated raw GraphQL logic and
should be removed or refactored to use the shared SDK: delete the orphaned
server action file if there are no call sites; otherwise replace the body of
analyzeMeeting to import executeFlow from lib/lamatic-client.ts, call
executeFlow({ workflowId: process.env.LAMATIC_FLOW_ID, payload: { meetingNotes,
recipientEmail } }) and return its result, and ensure environment flow IDs are
read from process.env as in the existing SDK abstraction.
In `@kits/automation/meeting-intelligence/app/api/analyze/route.ts`:
- Around line 6-40: Replace the in-file GraphQL fetch in analyze/route.ts with a
call to the shared Lamatic client: locate the duplicated logic that builds the
query, headers, variables (using workflowId, meetingNotes, recipientEmail) and
the response extraction, and instead call the exported executeFlow (or
executeWorkflow/executeFlowAsync) function from lib/lamatic-client.ts passing
meetingNotes and recipientEmail (and letting it supply auth/project/workflowId);
return the executeFlow result (or map its response to the same shape the route
expects) and remove the local fetch/query/response.json/result extraction so all
Lamatic request behavior is centralized in executeFlow.
- Around line 3-40: Protect the POST handler in route.ts by verifying an HS256
JWT from the Authorization: Bearer <token> header using the jose library and the
JWT_SECRET env var before executing the Lamatic call: in POST(req: NextRequest)
extract the bearer token, run jwtVerify(token, new
TextEncoder().encode(process.env.JWT_SECRET)) and return 401/403 for
missing/invalid tokens; only proceed to build and call Lamatic when verification
succeeds. Also add a new /api/token endpoint (e.g., a new POST handler) that
authenticates the client (validate a simple client credential or shared secret
from an env var like CLIENT_AUTH_SECRET) and issues a short-lived HS256 token
signed with process.env.JWT_SECRET and exp = 2 minutes (use jose SignJWT).
Ensure all token-related errors return appropriate 401 responses and do not
change the existing Lamatic call logic in POST except gating it behind the
verified token check.
In `@kits/automation/meeting-intelligence/app/globals.css`:
- Around line 22-26: The body selector in globals.css currently hard-codes
"font-family: Arial, Helvetica, sans-serif", which overrides the theme token
exposed as --font-sans in layout.tsx; either remove the body font-family
declaration or change it to use the theme token (font-family: var(--font-sans))
so the Geist font (--font-geist-sans) can take effect; update the body rule in
globals.css to reference --font-sans (or delete the rule) and verify layout.tsx
continues to set --font-sans correctly.
In `@kits/automation/meeting-intelligence/app/layout.tsx`:
- Around line 15-18: The exported metadata object (export const metadata:
Metadata) still contains the scaffold defaults ("Create Next App" / "Generated
by create next app"); update the metadata constant in layout.tsx to use
kit-appropriate values (e.g., title: "Meeting Intelligence" and a descriptive
description such as "AI-powered meeting summaries and insights from the Meeting
Intelligence kit") so the browser tab, social previews, and SEO reflect the app
identity.
In `@kits/automation/meeting-intelligence/app/page.tsx`:
- Around line 56-72: The copyToClipboard function currently calls
navigator.clipboard.writeText without awaiting it and immediately shows an
alert; make copyToClipboard async, await navigator.clipboard.writeText(text),
handle errors with a try/catch, call setError(...) on failure (and avoid showing
the success alert when writeText rejects), and only show the "Copied to
clipboard!" alert when the awaited writeText completes successfully; reference
the copyToClipboard function, result, navigator.clipboard.writeText, and
setError state in your changes.
- Around line 138-140: Replace inline SVG spinner and emoji/inline icons in the
component with lucide-react components: swap the spinner SVG (the animate-spin
circle/path) for Loader2, and replace emojis with ClipboardList, CheckCircle2,
User, Calendar, Hammer, and CircleHelp respectively; update any decorative
checkmark/question elements to use the appropriate icon variants from
lucide-react. Also fix the clipboard copy handler that calls
navigator.clipboard.writeText() by awaiting the Promise and only showing the
success alert after the await resolves, and add a catch to handle and surface
copy failures. Locate these changes around the spinner SVG, the emoji icon
usages (previously at lines referenced in the review), and the clipboard call to
navigator.clipboard.writeText() to apply the fixes.
In `@kits/automation/meeting-intelligence/config.json`:
- Around line 1-27: The config.json contains an empty documentationUrl which
will render as a dead link; update the "documentationUrl" field in config.json
to either a valid documentation URL (e.g., the kit README or demo docs) or
remove the "documentationUrl" key entirely so the catalog won't render an empty
anchor—ensure you modify the "documentationUrl" property in the existing JSON
rather than adding a duplicate key.
In
`@kits/automation/meeting-intelligence/flows/meeting-notes-extractor/config.json`:
- Around line 53-62: The config.json export includes account-specific credential
bindings (fields credentialId and credential_name inside the generativeModelName
entry for configA) and a personal SMTP credential; remove these sensitive
identifiers by clearing credentialId and credential_name (or setting them
null/empty) and ensure the node in the Lamatic Studio editor is unbound so users
must supply credentials via inputs.json; re-open the flow in the Studio node
editor, unbind/clear any credential selections for the generativeModelName node
(configName "configA") and the SMTP node, save and re-export the config.json so
the exported flow contains no account-specific credential bindings.
In
`@kits/automation/meeting-intelligence/flows/meeting-notes-extractor/meta.json`:
- Around line 3-8: The meta.json manifest for the Meeting Notes Extractor flow
is missing metadata fields; populate the "description", "tags", "testInput",
"githubUrl", "documentationUrl", and "deployUrl" keys with meaningful values (or
remove unused keys) so the kit catalog can render the card correctly; update the
"description" to a concise summary of the flow, add one or more comma-separated
"tags" for discovery, provide a representative "testInput" transcript snippet,
and fill "githubUrl", "documentationUrl", and "deployUrl" with the appropriate
repo/docs/deployment links (or omit keys if not applicable).
In
`@kits/automation/meeting-intelligence/flows/meeting-notes-extractor/README.md`:
- Around line 20-24: The package manifest currently omits README.md so exported
flows miss a required file; update the flow export manifest/packaging
configuration (the files array or export list for the flow export) to include
"README.md" alongside "config.json", "inputs.json", and "meta.json" so all four
required files in the flows/ directory are bundled; locate the export
configuration or function responsible for building the flow package (e.g., the
manifest/files array or export list used by the flow exporter) and add
"README.md" to that list, then run the flow export to verify README.md is
included.
In `@kits/automation/meeting-intelligence/lib/lamatic-client.ts`:
- Around line 8-39: The executeFlow function silently swallows failures and can
hang; update executeFlow to (1) tighten the payload type to { meetingNotes:
string; recipientEmail: string } so callers can't pass unexpected keys, (2)
attach an AbortController with a configurable timeout to the fetch call using
lamaticConfig or a default, (3) check response.ok and, if false, parse and
include HTTP status and body text in a structured error, (4) defensively parse
JSON (handle non-JSON body) and surface GraphQL-level errors by returning or
throwing a detailed object that includes response.status, statusText, any parsed
errors array, and the raw body, and (5) avoid returning a generic { error: "No
result" } so callers (e.g., actions/orchestrate.ts and app/api/analyze/route.ts)
can distinguish auth/validation/server/parse/timeout failures; locate and modify
executeFlow, lamaticConfig usage, and the fetch/response handling to implement
these changes.
- Around line 1-6: Replace the custom fetch+GraphQL implementation in
lib/lamatic-client.ts (and the exported lamaticConfig object) with the standard
SDK pattern used elsewhere: validate presence of process.env.LAMATIC_API_URL,
process.env.LAMATIC_PROJECT_ID and process.env.LAMATIC_API_KEY early and throw a
clear Error if missing, then instantiate and export a single lamaticClient = new
Lamatic({ endpoint: process.env.LAMATIC_API_URL, projectId:
process.env.LAMATIC_PROJECT_ID, apiKey: process.env.LAMATIC_API_KEY }); remove
the brittle hardcoded GraphQL query logic that only handles
meetingNotes/recipientEmail so payload keys aren’t dropped and rely on the SDK’s
typing/retries/schema validation instead.
In `@kits/automation/meeting-intelligence/package.json`:
- Around line 16-25: Update package.json devDependencies to use exact pinned
versions instead of caret ranges: replace "@tailwindcss/postcss", "@types/node",
"@types/react", "@types/react-dom", "eslint", "eslint-config-next",
"tailwindcss", and "typescript" entries in the devDependencies object with
concrete version strings you have tested (no ^ or ~), ensuring each value is a
single exact version; keep the same keys and only change the version strings so
builds are reproducible.
- Line 9: The package.json "lint" script currently is just "eslint" with no
target; update the "lint" npm script entry (the "lint" key in package.json) to
invoke ESLint against the current directory (e.g., include "./" or "." as the
target) so it runs deterministically after the Next.js upgrade—modify the "lint"
script value to include the directory target.
In `@kits/automation/meeting-intelligence/README.md`:
- Around line 118-125: The README currently instructs users to recreate the five
Lamatic nodes manually; instead update it to tell users to import the shipped
flow export at flows/meeting-notes-extractor/ into Lamatic Studio, deploy that
imported flow, and set its private inputs (SMTP and project credentials) via the
flow's inputs (e.g., inputs.json) or Lamatic Connections; ensure you reference
the included export files (config.json, inputs.json, meta.json, README.md) and
instruct users to copy the Flow ID and any required project credentials into
.env.local after import.
- Around line 93-99: Replace the standalone repo clone instructions with steps
that instruct users to clone the main AgentKit repository and then change into
this kit's directory; specifically update the README.md's setup section to run
git clone for the AgentKit repo and then cd into
kits/automation/meeting-intelligence so users land in this kit (edit the section
that currently contains the standalone repo URL and thegit clone/cd commands).
- Around line 193-194: Update the broken relative link to the repository
CONTRIBUTING.md in the README: locate the link text "CONTRIBUTING.md" in
kits/automation/meeting-intelligence/README.md (the lines containing "See
[CONTRIBUTING.md](../../CONTRIBUTING.md) for guidelines.") and change the path
from ../../CONTRIBUTING.md to ../../../CONTRIBUTING.md so it correctly points to
the repository root CONTRIBUTING.md.
🪄 Autofix (Beta)
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
Run ID: 95945cc0-5cd3-4bff-957b-b02e0fda8aa4
⛔ Files ignored due to path filters (6)
kits/automation/meeting-intelligence/app/favicon.icois excluded by!**/*.icokits/automation/meeting-intelligence/public/file.svgis excluded by!**/*.svgkits/automation/meeting-intelligence/public/globe.svgis excluded by!**/*.svgkits/automation/meeting-intelligence/public/next.svgis excluded by!**/*.svgkits/automation/meeting-intelligence/public/vercel.svgis excluded by!**/*.svgkits/automation/meeting-intelligence/public/window.svgis excluded by!**/*.svg
📒 Files selected for processing (18)
kits/automation/meeting-intelligence/.env.examplekits/automation/meeting-intelligence/.gitignorekits/automation/meeting-intelligence/README.mdkits/automation/meeting-intelligence/actions/orchestrate.tskits/automation/meeting-intelligence/app/api/analyze/route.tskits/automation/meeting-intelligence/app/globals.csskits/automation/meeting-intelligence/app/layout.tsxkits/automation/meeting-intelligence/app/page.tsxkits/automation/meeting-intelligence/config.jsonkits/automation/meeting-intelligence/flows/meeting-notes-extractor/README.mdkits/automation/meeting-intelligence/flows/meeting-notes-extractor/config.jsonkits/automation/meeting-intelligence/flows/meeting-notes-extractor/inputs.jsonkits/automation/meeting-intelligence/flows/meeting-notes-extractor/meta.jsonkits/automation/meeting-intelligence/lib/lamatic-client.tskits/automation/meeting-intelligence/next.config.tskits/automation/meeting-intelligence/package.jsonkits/automation/meeting-intelligence/postcss.config.mjskits/automation/meeting-intelligence/tsconfig.json
| export async function analyzeMeeting(meetingNotes: string, recipientEmail: string) { | ||
| const query = ` | ||
| query ExecuteWorkflow($workflowId: String!, $meetingNotes: String, $recipientEmail: String) { | ||
| executeWorkflow( | ||
| workflowId: $workflowId | ||
| payload: { meetingNotes: $meetingNotes, recipientEmail: $recipientEmail } | ||
| ) { | ||
| status | ||
| result | ||
| } | ||
| } | ||
| `; | ||
|
|
||
| const response = await fetch(process.env.LAMATIC_API_URL!, { | ||
| method: "POST", | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| "Authorization": `Bearer ${process.env.LAMATIC_API_KEY}`, | ||
| "x-project-id": process.env.LAMATIC_PROJECT_ID!, | ||
| }, | ||
| body: JSON.stringify({ | ||
| query, | ||
| variables: { | ||
| workflowId: process.env.LAMATIC_FLOW_ID, | ||
| meetingNotes, | ||
| recipientEmail, | ||
| }, | ||
| }), | ||
| }); | ||
|
|
||
| const data = await response.json(); | ||
| const result = data?.data?.executeWorkflow?.result?.result; | ||
| return result ?? { error: "No result" }; | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Expect: either no call sites for analyzeMeeting (safe to remove) or SDK-backed flow invocation.
rg -nP -C3 '\banalyzeMeeting\s*\(' kits/automation/meeting-intelligence
rg -nP -C3 '(`@lamatic`|Lamatic|executeWorkflow|executeFlow)' kits/automation/meeting-intelligence
fd -i '^package\.json$' kits/automation/meeting-intelligence -x sh -c 'printf "\n== %s ==\n" "$1"; sed -n "1,220p" "$1"' sh {}Repository: Lamatic/AgentKit
Length of output: 16240
Mission critical: eliminate the orphaned server action and route flow execution through the shared abstraction.
analyzeMeeting() violates the kit guideline by using raw GraphQL fetch instead of the SDK-backed executeFlow() abstraction already present in lib/lamatic-client.ts. The function has no call sites in the codebase and duplicates logic that exists elsewhere. Remove this server action entirely; if flow invocation from a server action is needed, refactor to import and use executeFlow() from lamatic-client.ts.
Per coding guidelines, kit server action files must call Lamatic flows via the SDK and read flow IDs from environment variables. This file currently bypasses the shared abstraction and maintains dead code.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@kits/automation/meeting-intelligence/actions/orchestrate.ts` around lines 3 -
36, analyzeMeeting contains duplicated raw GraphQL logic and should be removed
or refactored to use the shared SDK: delete the orphaned server action file if
there are no call sites; otherwise replace the body of analyzeMeeting to import
executeFlow from lib/lamatic-client.ts, call executeFlow({ workflowId:
process.env.LAMATIC_FLOW_ID, payload: { meetingNotes, recipientEmail } }) and
return its result, and ensure environment flow IDs are read from process.env as
in the existing SDK abstraction.
| const query = ` | ||
| query ExecuteWorkflow($workflowId: String!, $meetingNotes: String, $recipientEmail: String) { | ||
| executeWorkflow( | ||
| workflowId: $workflowId | ||
| payload: { meetingNotes: $meetingNotes, recipientEmail: $recipientEmail } | ||
| ) { | ||
| status | ||
| result | ||
| } | ||
| } | ||
| `; | ||
|
|
||
| const response = await fetch(process.env.LAMATIC_API_URL!, { | ||
| method: "POST", | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| "Authorization": `Bearer ${process.env.LAMATIC_API_KEY}`, | ||
| "x-project-id": process.env.LAMATIC_PROJECT_ID!, | ||
| }, | ||
| body: JSON.stringify({ | ||
| query, | ||
| variables: { | ||
| workflowId: process.env.LAMATIC_FLOW_ID, | ||
| meetingNotes, | ||
| recipientEmail, | ||
| }, | ||
| }), | ||
| }); | ||
|
|
||
| const data = await response.json(); | ||
|
|
||
|
|
||
| const result = data?.data?.executeWorkflow?.result?.result; | ||
|
|
||
| return NextResponse.json(result ?? { error: "No result" }); |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Mission cleanup: reuse the shared Lamatic flow client.
This route duplicates the GraphQL query, headers, variables, and result extraction already present in lib/lamatic-client.ts. After adding auth, call executeFlow() here to keep Lamatic request behavior in one place.
♻️ Proposed refactor
import { NextRequest, NextResponse } from "next/server";
+import { executeFlow } from "@/lib/lamatic-client";
export async function POST(req: NextRequest) {
const { meetingNotes, recipientEmail } = await req.json();
-
- const query = `
- query ExecuteWorkflow($workflowId: String!, $meetingNotes: String, $recipientEmail: String) {
- executeWorkflow(
- workflowId: $workflowId
- payload: { meetingNotes: $meetingNotes, recipientEmail: $recipientEmail }
- ) {
- status
- result
- }
- }
- `;
-
- const response = await fetch(process.env.LAMATIC_API_URL!, {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- "Authorization": `Bearer ${process.env.LAMATIC_API_KEY}`,
- "x-project-id": process.env.LAMATIC_PROJECT_ID!,
- },
- body: JSON.stringify({
- query,
- variables: {
- workflowId: process.env.LAMATIC_FLOW_ID,
- meetingNotes,
- recipientEmail,
- },
- }),
- });
-
- const data = await response.json();
-
-
- const result = data?.data?.executeWorkflow?.result?.result;
-
- return NextResponse.json(result ?? { error: "No result" });
+ const result = await executeFlow({ meetingNotes, recipientEmail });
+ return NextResponse.json(result);
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@kits/automation/meeting-intelligence/app/api/analyze/route.ts` around lines 6
- 40, Replace the in-file GraphQL fetch in analyze/route.ts with a call to the
shared Lamatic client: locate the duplicated logic that builds the query,
headers, variables (using workflowId, meetingNotes, recipientEmail) and the
response extraction, and instead call the exported executeFlow (or
executeWorkflow/executeFlowAsync) function from lib/lamatic-client.ts passing
meetingNotes and recipientEmail (and letting it supply auth/project/workflowId);
return the executeFlow result (or map its response to the same shape the route
expects) and remove the local fetch/query/response.json/result extraction so all
Lamatic request behavior is centralized in executeFlow.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Replaced raw fetch call with executeFlow function for executing workflows.
What This Kit Does
Transforms raw, messy meeting notes into structured action items, decisions, and follow-up questions — and automatically emails the report to your team.
Providers & Prerequisites
How to Run Locally
cd kits/automation/meeting-intelligencenpm installcp .env.example .env.localand fill in valuesnpm run devLive Preview
https://meeting-intelligence-tau.vercel.app/
Lamatic Flow
Flow ID:
meeting-notes-extractorFlow Architecture
API Request → Generate Text (Llama 3.3 70B via Groq) → Code Node (JSON parser + HTML builder) → SMTP Node (email delivery) → API Response
PR Checklist
npm run dev.env.examplehas no secrets, only placeholdersREADME.mddocuments setup and usagekits/automation/meeting-intelligence/config.jsonis present and validFiles Added
Configuration & Setup:
.gitignore- Excludesnode_modules/,.env,.env.local, and.next/package.json- Project metadata and dependencies (Next.js, React, React-DOM, Tailwind, PostCSS, ESLint, TypeScript)tsconfig.json- TypeScript configuration with strict mode, ES2017 target, and Next.js plugin supportnext.config.ts- Next.js configuration placeholderpostcss.config.mjs- PostCSS configuration with Tailwind pluginconfig.json- Kit configuration defining "Meeting Intelligence Agent" with Groq and SMTP integrationsFrontend & UI:
app/layout.tsx- Next.js root layout with Geist fonts and metadataapp/page.tsx- React UI component for meeting analysis with form inputs, result display (summary, action items, decisions, follow-ups), and clipboard copy functionalityapp/globals.css- Tailwind CSS integration with light/dark theme variablesBackend & API:
app/api/analyze/route.ts- Next.js POST API route that validates input and calls Lamatic workflowactions/orchestrate.ts- Server-side action exportinganalyzeMeeting()function for GraphQL workflow executionlib/lamatic-client.ts- Lamatic API client withlamaticConfigandexecuteFlow()for managing workflow interactionsFlow Definition:
flows/meeting-notes-extractor/config.json- Main flow configurationflows/meeting-notes-extractor/inputs.json- Input parameter definitions for LLM and SMTP nodesflows/meeting-notes-extractor/meta.json- Flow metadata (name, description placeholders)flows/meeting-notes-extractor/README.md- Flow documentation and contribution guidelinesDocumentation:
README.md- Kit documentation with setup instructions, prerequisites, environment variables, local run steps, and Vercel deployment guidanceMeeting Notes Extractor Flow Architecture
Node Types & Workflow:
meetingNotesandrecipientEmailpayloadresultto the API callerEnd-to-End Flow: API Request → Groq LLM (Llama 3.3 70B) → JSON Parsing & HTML Email Building → SMTP Email Delivery → API Response, enabling automated transformation of unstructured meeting notes into actionable intelligence and team notification.