Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ Each kit includes configuration instructions, environment variables/lamatic-conf
| **🧠 Agentic Kits** | Advanced self-directed, reasoning agents for goal-driven operations | | | [`/kits/agentic`](./kits/agentic) |
| **Deep Search Agent** | A Next.js starter kit for goal-driven reasoning agents using Lamatic Flows. | Available | [![Live Demo](https://img.shields.io/badge/Live%20Demo-black?style=for-the-badge)](https://agent-kit-reasoning.vercel.app) | [`/kits/agentic/deep-search`](./kits/agentic/deep-search) |
| **Generation Agent** | A Next.js starter kit for generating text/json/image content using Lamatic Flows. | Available | [![Live Demo](https://img.shields.io/badge/Live%20Demo-black?style=for-the-badge)](https://agent-kit-generation.vercel.app) | [`/kits/agentic/generation`](./kits/agentic/generation) |
| **Comparison Agent** | A Next.js starter kit for deep research and comparison between two entities. | Available | [![Live Demo](https://img.shields.io/badge/Live%20Demo-black?style=for-the-badge)](https://agent-kit-comparison.vercel.app) | [`/kits/agentic/comparison-engine`](./kits/agentic/comparison-engine) |
||
| **🤖 Automation Kits** | Automate complex business processes with robust and flexible agent workflows | | | [`/kits/automation`](./kits/automation) |
| **Hiring Automation** | A Next.js starter kit for hiring automation using Lamatic Flows. | Available | [![Live Demo](https://img.shields.io/badge/Live%20Demo-black?style=for-the-badge)](https://agent-kit-hiring.vercel.app) | [`/kits/automation/hiring`](./kits/automation/hiring) |
Expand Down
10 changes: 10 additions & 0 deletions kits/agentic/comparison-engine/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Comparison Engine Flow IDs
COMPARISON_RESEARCH_A="ID for Researching Entity A"
COMPARISON_RESEARCH_B="ID for Researching Entity B"
COMPARISON_ANALYZE="ID for Analyzing Differences"
COMPARISON_VERDICT="ID for Expert Verdict"

# Lamatic Project Config
LAMATIC_API_URL="your_lamatic_url"
LAMATIC_PROJECT_ID="your_project_id"
LAMATIC_API_KEY="your_api_key"
33 changes: 33 additions & 0 deletions kits/agentic/comparison-engine/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules

# next.js
/.next/
/out/

# production
/build

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# env files
.env

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

# package manager
package-lock.json
yarn.lock
pnpm-lock.yaml
bun.lockb
53 changes: 53 additions & 0 deletions kits/agentic/comparison-engine/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Agentic Comparison Engine Kit by Lamatic.ai

**Agentic Comparison Engine** is a specialized AI-powered kit for deep research and comparison between two entities (products, services, companies, etc.). It uses an agentic workflow to research both entities independently, analyze their differences, and generate a structured comparison table with an expert recommendation.

## Features
- **Dual Research Pipeline**: Researches two entities simultaneously or sequentially.
- **Structured Analysis**: Automatically extracts key features and metrics for comparison.
- **Expert Verdict**: Provides a reasoning-based "Best Choice" recommendation.
- **Side-by-Side UI**: Responsive comparison dashboard with a clean data table.

## Lamatic Setup

1. Sign in or sign up at [https://lamatic.ai](https://lamatic.ai)
2. Create a new flow from the **Comparison Engine** template.
3. Obtain your `.env` keys from the Lamatic Studio.

## Required Environment Variables

Set the following in your `.env` file:

```bash
# Lamatic Project Config
LAMATIC_API_URL="your_lamatic_url"
LAMATIC_PROJECT_ID="your_project_id"
LAMATIC_API_KEY="your_api_key"

# Flow IDs
COMPARISON_RESEARCH_A="Flow ID for Researching Entity A"
COMPARISON_RESEARCH_B="Flow ID for Researching Entity B"
COMPARISON_ANALYZE="Flow ID for Analyzing Differences"
COMPARISON_VERDICT="Flow ID for Expert Verdict"
```

## Getting Started

1. Clone the repository and navigate to the kit:
```sh
cd kits/agentic/comparison-engine
```
2. Install dependencies:
```sh
npm install
```
3. Run the development server:
```sh
npm run dev
```

## Repo Structure
- `/app/page.tsx`: Main comparison interface.
- `/actions/orchestrate.ts`: Server actions for orchestration.
- `/components/ComparisonTable.tsx`: Side-by-side data visualization.
- `/orchestrate.js`: Workflow process definition.
109 changes: 109 additions & 0 deletions kits/agentic/comparison-engine/actions/orchestrate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
"use server"

import { lamaticClient } from "@/lib/lamatic-client"
import { config } from "../orchestrate.js"

interface FlowConfig {
name: string
workflowId: string
description: string
mode: "sync" | "async"
expectedOutput: string | string[]
inputSchema: Record<string, string>
outputSchema: Record<string, string>
dependsOn?: string[]
}

const flows = config.flows as Record<string, FlowConfig>

export async function orchestratePipelineStep(
query: string,
history: any[],
step: string,
previousResults?: Record<string, any>,
): Promise<{
success: boolean
stepId: string
stepName: string
data?: any
error?: string
}> {
try {
const flow = flows[step]

if (!flow) {
return {
success: false,
stepId: step,
stepName: step,
error: `Step ${step} not found in config`,
}
}

console.log(`[ComparisonKit] Executing ${step}: ${flow.name}`)

const inputs: Record<string, any> = {}

// Fill inputs based on schema
for (const inputKey of Object.keys(flow.inputSchema)) {
if (inputKey === "entity") {
inputs[inputKey] = query // In research steps, query is the entity name
} else if (inputKey === "criteria") {
inputs[inputKey] = query // or explicit criteria
} else if (previousResults && previousResults[inputKey] !== undefined) {
inputs[inputKey] = previousResults[inputKey]
}
}

// Special handling for the compare step
if (step === "compare_entities" && previousResults) {
inputs.research_a = previousResults.research_a
inputs.research_b = previousResults.research_b
inputs.criteria = previousResults.criteria
}

// Special handling for verdict step
if (step === "final_verdict" && previousResults) {
inputs.comparison_data = previousResults.comparison_data
inputs.criteria = previousResults.criteria
}

console.log(`[ComparisonKit] ${step} inputs:`, JSON.stringify(inputs, null, 2))

if (!flow.workflowId) {
throw new Error(`Workflow ID for ${step} is not configured in .env`)
}

const resData = await lamaticClient.executeFlow(flow.workflowId, inputs)

if (!resData.result) {
throw new Error(`No result returned from Lamatic for step ${step}`)
}

const output: Record<string, any> = {}

// Store declared outputs from outputSchema
for (const key of Object.keys(flow.outputSchema)) {
if (resData.result[key] !== undefined) {
output[key] = resData.result[key]
}
}

console.log(`[ComparisonKit] ${step} final output:`, JSON.stringify(output, null, 2))

return {
success: true,
stepId: step,
stepName: flow.name,
data: output,
}
} catch (error) {
console.error(`[ComparisonKit] Error executing ${step}:`, error)
return {
success: false,
stepId: step,
stepName: flows[step]?.name || step,
error: error instanceof Error ? error.message : "Unknown error occurred",
}
}
}
125 changes: 125 additions & 0 deletions kits/agentic/comparison-engine/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
@import 'tailwindcss';
@import 'tw-animate-css';

@custom-variant dark (&:is(.dark *));

:root {
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--destructive-foreground: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--radius: 0.625rem;
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
}

.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.145 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.145 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.985 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.396 0.141 25.723);
--destructive-foreground: oklch(0.637 0.237 25.331);
--border: oklch(0.269 0 0);
--input: oklch(0.269 0 0);
--ring: oklch(0.439 0 0);
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(0.269 0 0);
--sidebar-ring: oklch(0.439 0 0);
}

@theme inline {
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
}

@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
}
Binary file added kits/agentic/comparison-engine/app/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions kits/agentic/comparison-engine/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type React from "react"
import type { Metadata } from "next"
import { GeistSans } from "geist/font/sans"
import { GeistMono } from "geist/font/mono"
import { Analytics } from "@vercel/analytics/next"
import { Suspense } from "react"
import "./globals.css"

export const metadata: Metadata = {
title: "Agent Kit Reasoning",
description: "AI-powered search and chat interface by Lamatic.ai",
generator: "v0.app",
}

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html lang="en">
<body className={`font-sans ${GeistSans.variable} ${GeistMono.variable}`}>
<Suspense fallback={null}>{children}</Suspense>
<Analytics />
</body>
</html>
)
}
Loading