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