Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0b10129
feat: Add Founder Lens - AI Startup Research Agent
cyber-turtle Mar 23, 2026
c5126a2
docs: align README with challenge rubric
cyber-turtle Mar 23, 2026
7317720
chore: add vercel demo url to config.json
cyber-turtle Mar 23, 2026
db1b262
docs: clarify Exa.ai API node configuration
cyber-turtle Mar 23, 2026
30ae731
fix: improve UX for founder-lens - fix progress bar timing, add timeo…
cyber-turtle Mar 23, 2026
fbef69d
docs: add JSDoc docstrings to improve coverage to > 80% and satisfy P…
cyber-turtle Mar 24, 2026
4e1b062
Update kits/agentic/founder-lens/components/IdeaForm.tsx
cyber-turtle Mar 24, 2026
5220ade
addressing Search count mismatch in analyze README
cyber-turtle Mar 24, 2026
72d4862
docs: resolve search count inconsistencies and fix markdown linting i…
cyber-turtle Mar 24, 2026
324999a
Update kits/agentic/founder-lens/lib/lamatic-client.ts
cyber-turtle Mar 24, 2026
ee4fd4f
fix: add timeout to chatWithBrief and resolve icon/CSS/doc issues
cyber-turtle Mar 24, 2026
23020e1
fix: disable suggested questions during loading in ChatInterface and …
cyber-turtle Mar 24, 2026
86bd0cc
Update kits/agentic/founder-lens/components/IdeaForm.tsx
cyber-turtle Mar 24, 2026
5bc518b
Revert "Update kits/agentic/founder-lens/components/IdeaForm.tsx"
cyber-turtle Mar 24, 2026
7c8e01e
feat: increase analyzeIdea timeout to 5 minutes
cyber-turtle Mar 24, 2026
7353d11
feat: increase analysis timeout to 10mins and add 'taking longer than…
cyber-turtle Mar 24, 2026
84c41d8
fix: improve JSON parsing robustness in BriefDisplay
cyber-turtle Mar 24, 2026
9ee28f4
fix: add maxDuration for Vercel and adjust UI message timing
cyber-turtle Mar 24, 2026
1b48e23
fix: move maxDuration from server action file to page to fix build error
cyber-turtle Mar 24, 2026
5418926
fix: adjust timeout to 300s to satisfy Vercel Hobby plan limits
cyber-turtle Mar 24, 2026
67b4719
Merge branch 'main' into feat/founder-lens
cyber-turtle Mar 31, 2026
d837f51
docs: add live demo link to README
cyber-turtle Mar 31, 2026
a330b6d
docs: add screenshot to README
cyber-turtle Mar 31, 2026
879aa15
docs: add screenshot file to repository
cyber-turtle Mar 31, 2026
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
5 changes: 5 additions & 0 deletions kits/agentic/founder-lens/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FOUNDER_LENS_ANALYZE_FLOW_ID="YOUR_ANALYZE_FLOW_ID"
FOUNDER_LENS_CHAT_FLOW_ID="YOUR_CHAT_FLOW_ID"
LAMATIC_API_URL="YOUR_API_ENDPOINT"
LAMATIC_PROJECT_ID="YOUR_PROJECT_ID"
LAMATIC_API_KEY="YOUR_API_KEY"
6 changes: 6 additions & 0 deletions kits/agentic/founder-lens/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules/
.next/
.env.local
.env
.DS_Store
*.log
174 changes: 174 additions & 0 deletions kits/agentic/founder-lens/README.md
Comment thread
cyber-turtle marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# Founder Lens — AI Startup Research Agent

> Get a brutally honest investor-grade brief on your startup idea — built from real web data in ~90 seconds. Then chat with your analysis using RAG-powered persistent memory.

![Built with Lamatic](https://img.shields.io/badge/Built%20with-Lamatic-5B21B6?style=flat-square)
![Powered by Exa.ai](https://img.shields.io/badge/Powered%20by-Exa.ai-0EA5E9?style=flat-square)
![GPT-4o](https://img.shields.io/badge/GPT--4o-OpenRouter-10B981?style=flat-square)
![agentkit-challenge](https://img.shields.io/badge/challenge-agentkit-F59E0B?style=flat-square)

[**Live Demo →**](https://founder-lens-agentkit.vercel.app/)

![Founder Lens Screenshot](public/sample.png)

---

## 1. The Problem

Non-technical founders spend weeks manually researching whether their idea is viable. They scour Reddit, Crunchbase, and postmortems — and still miss critical blind spots. They need an investor-grade analysis without spending thousands of dollars or hundreds of hours on manual data collection.

---

## 2. The Approach

Founder Lens completely automates this research process in ~90 seconds using a 7-phase autonomous agent. Submit a startup idea and two Lamatic flows run in sequence:

**Flow 1 — Analyze:** Deconstructs your idea into 8 targeted search queries, then fires 10 parallel Exa.ai web searches across:
- **Market size** — TAM/SAM/SOM data
- **VC funding signals** — Crunchbase trends and recent rounds
- **Direct competitors** — mapping the competitive landscape
- **Failed startup postmortems** — what already tried and died
- **Customer complaints** — verbatim from Reddit, G2, HN, Capterra
- **LinkedIn complaint signals** — professional pain signal mining
- **Success stories** — IndieHackers, YC, TechCrunch breakouts
- **Business model benchmarks** — pricing and monetization data
- **Unfair advantage signals** — what makes winners different

Then a dedicated **Contrarian VC Persona** runs a separate pass to find the fatal flaw. The synthesized result is a structured Founder Brief stored in **Weaviate vector DB** and **Lamatic semantic memory**.

**Flow 2 — Chat:** The founder sends messages and the system retrieves the stored brief via RAG + semantic memory and answers questions using GPT-4o with full context of the brief and conversation history.

---

## 3. The Result

Founder Lens saves founders immense time, reduces manual work entirely, and provides extreme clarity. It delivers the exact brief a VC analyst would write internally before taking a meeting, creating a repeatable workflow for testing new startup ideas before writing a single line of code. It even features an audio completion chime when the 90-second semantic analysis finishes, allowing founders to safely multi-task while the agent runs.

---

## 4. Tradeoffs & Assumptions

**Tradeoffs:**
- **Speed vs. Exhaustive Depth:** We chose to run 9 highly targeted parallel searches to keep the analysis under 90 seconds. We trade off multi-hour, deeply exhaustive agentic crawling for immediate, highly actionable insights.
- **Frictionless UX:** The chat history is maintained in Lamatic semantic memory. Because we wanted a frictionless UX, we generate a unique `userId` and `sessionId` in `localStorage` automatically instead of requiring users to create accounts and log in securely.

**Assumptions:**
- We assume the user's idea revolves around software/tech. Extremely niche physical hardware, biotech, or offline local services might not yield as much verbatim complaint data on Reddit or G2.
- The high quality of the analysis assumes Exa.ai can successfully retrieve highly semantic, relevant forum threads and news articles based on the generated keyword queries.

---

## Tech Stack

| Layer | Technology |
|---|---|
| Flow orchestration, RAG, memory | **Lamatic.ai** |
| Neural web search (10 parallel) | **Exa.ai** |
| Analysis synthesis & chat | **OpenRouter / GPT-4o** |
| Idea deconstruction | **OpenRouter / Claude 3.5 Sonnet** |
| Vector embeddings | **Gemini gemini-embedding-001** |
| Vector database | **Weaviate** (via Lamatic) |
| Frontend | **Next.js 14** (TypeScript, Tailwind CSS) |

---

## Prerequisites

- Node.js 18+
- A [Lamatic.ai](https://lamatic.ai) account with both flows deployed
- An OpenRouter API key (configured in Lamatic as a credential)
- A Gemini API key (configured in Lamatic as a credential)
- **An Exa.ai API key:** You must create an account on [Exa.ai](https://exa.ai) to get an API key. Once you import the Analyze flow into Lamatic, click on each individual Exa search node. Under the Headers section, manually input your API key into the `x-api-key` field (as a key-value pair).

---

## Setup Instructions

1. **Clone and navigate to the kit folder**
```bash
git clone https://github.com/Lamatic/AgentKit.git
cd AgentKit/kits/agentic/founder-lens
```

2. **Install dependencies**
```bash
npm install
```

3. **Set up environment variables**
```bash
cp .env.example .env.local
```
Then fill in `.env.local` with your real values (see table below).

4. **Start the development server**
```bash
npm run dev
```

5. **Open your browser**
```text
http://localhost:3000
```

---

## Environment Variables

| Variable | Description | Where to Find |
|---|---|---|
| `FOUNDER_LENS_ANALYZE_FLOW_ID` | Flow ID for the analysis flow | Lamatic Studio → your flow → three-dot menu → Flow ID |
| `FOUNDER_LENS_CHAT_FLOW_ID` | Flow ID for the chat flow | Lamatic Studio → your flow → three-dot menu → Flow ID |
| `LAMATIC_API_URL` | Your project API endpoint | Lamatic Studio → Settings → API Docs |
| `LAMATIC_PROJECT_ID` | Your project ID | Lamatic Studio → Settings → Project |
| `LAMATIC_API_KEY` | Your API key | Lamatic Studio → Settings → API Keys |

---

## Flows

### Analyze Flow
**Input:** `{ idea: string, userId: string, sessionId: string }`
**Output:** `{ brief: string (JSON), decomposition: string (JSON) }`

Runs the full 7-phase research pipeline, synthesizes a Founder Brief JSON, and stores it in Weaviate + semantic memory.

### Chat Flow
**Input:** `{ message: string, userId: string, sessionId: string }`
**Output:** `{ answer: string }`

Retrieves the indexed brief and conversation history from memory, then answers the founder's question with full context.

> **Important:** The analyze flow must run first for a given `userId` + `sessionId` pair before the chat flow has any context to retrieve.

---

## Deploy to Vercel

1. Push your branch to GitHub:
```bash
git checkout -b feat/founder-lens
git add kits/agentic/founder-lens/
git commit -m "feat: Add Founder Lens - AI Startup Research Agent"
git push origin feat/founder-lens
```

2. Go to [vercel.com](https://vercel.com) and import your repo

3. Set the **root directory** to `kits/agentic/founder-lens`

4. Add all environment variables from the table above

5. Click **Deploy**

---

## Contributing

This kit was built for the [agentkit-challenge](https://github.com/Lamatic/AgentKit). To open a PR:

```text
github.com/Lamatic/AgentKit/compare/main...YOUR-USERNAME:feat/founder-lens?expand=1
```

Add the `agentkit-challenge` label to your PR.
79 changes: 79 additions & 0 deletions kits/agentic/founder-lens/actions/orchestrate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"use server";

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

const TIMEOUT_MS = 300000; // 5 minutes (Matching Vercel Hobby maxDuration)

/**
* Wraps a promise with a timeout.
* @param promise The promise to wrap.
* @param timeoutMs Timeout in milliseconds.
* @param errorMessage Message to throw on timeout.
* @returns The original promise result or throws a timeout error.
*/
async function withTimeout<T>(promise: Promise<T>, timeoutMs: number, errorMessage: string): Promise<T> {
const timeoutPromise = new Promise<never>((_, reject) => {
setTimeout(() => reject(new Error(errorMessage)), timeoutMs);
});
return Promise.race([promise, timeoutPromise]);
}

/**
* Executes the Lamatic analyze flow to generate a Founder Brief.
* @param idea The startup idea to analyze.
* @param userId Unique user identifier for session persistence.
* @param sessionId Unique session identifier for the analysis.
* @returns Object containing success status, generated brief, and idea decomposition.
*/
export async function analyzeIdea(
idea: string,
userId: string,
sessionId: string
): Promise<{ success: boolean; brief?: string; decomposition?: string; error?: string }> {
try {
const flow = config.flows.analyze;
if (!flow.workflowId) throw new Error("FOUNDER_LENS_ANALYZE_FLOW_ID is not set.");

// Wrap the flow execution in a timeout
const resData: any = await withTimeout(
lamaticClient.executeFlow(flow.workflowId, { idea, userId, sessionId }),
TIMEOUT_MS,
"The AI provider is taking longer than usual to respond. This usually means their service is overloaded. Please try again in a few minutes."
);

const brief = resData?.result?.brief;
if (!brief) throw new Error("No brief returned from analyze flow.");
return { success: true, brief, decomposition: resData?.result?.decomposition };
} catch (error) {
return { success: false, error: error instanceof Error ? error.message : "Unknown error" };
}
}

/**
* Sends a chat message to the RAG-powered Lamatic chat flow.
* @param message The user's follow-up question.
* @param userId Unique user identifier.
* @param sessionId Unique session identifier.
* @returns Object containing the assistant's answer.
*/
export async function chatWithBrief(
message: string,
userId: string,
sessionId: string
): Promise<{ success: boolean; answer?: string; error?: string }> {
try {
const flow = config.flows.chat;
if (!flow.workflowId) throw new Error("FOUNDER_LENS_CHAT_FLOW_ID is not set.");
const resData: any = await withTimeout(
lamaticClient.executeFlow(flow.workflowId, { message, userId, sessionId }),
90000, // 90 second timeout for chat
"The AI Analyst is taking too long to respond. Please try a shorter question or try again later."
);
const answer = resData?.result?.answer;
if (!answer) throw new Error("No answer returned from chat flow.");
return { success: true, answer };
} catch (error) {
return { success: false, error: error instanceof Error ? error.message : "Unknown error" };
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
99 changes: 99 additions & 0 deletions kits/agentic/founder-lens/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
@import url('https://fonts.googleapis.com/css2?family=Google+Sans:ital,opsz,wght@0,17..18,400..700;1,17..18,400..700&display=swap');

@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
--background: #000000;
--foreground: #ffffff;
--border: rgba(255, 255, 255, 0.08);
--primary: #ffffff;
--primary-foreground: #000000;
--muted: rgba(255, 255, 255, 0.05);
--muted-foreground: rgba(255, 255, 255, 0.5);
--clay-shadow: rgba(0, 0, 0, 0.25);
}

@layer base {
* {
border-color: var(--border);
box-sizing: border-box;
}
body {
background-color: var(--background);
color: var(--foreground);
font-family: "Google Sans", sans-serif;
font-optical-sizing: auto;
font-variation-settings: "GRAD" 0;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
}

/* --- LIQUID GLASS --- */

.liquid-glass {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.06) 0%, rgba(255, 255, 255, 0.01) 100%);
backdrop-filter: blur(40px) saturate(150%);
-webkit-backdrop-filter: blur(40px) saturate(150%);
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow:
0 8px 32px 0 rgba(0, 0, 0, 0.37),
inset 0 1px 1px 0 rgba(255, 255, 255, 0.1);
border-radius: 1.25rem;
}

.liquid-glass-pill {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.02) 100%);
backdrop-filter: blur(20px) saturate(120%);
border: 1px solid rgba(255, 255, 255, 0.12);
box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.15);
border-radius: 9999px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.liquid-glass-pill:hover {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.05) 100%);
transform: translateY(-1px);
}

.glass-panel {
background: rgba(255, 255, 255, 0.03);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.06);
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
border-radius: 1.5rem;
}

/* --- AURORA BG --- */

.aurora-bg {
position: fixed;
top: 0; left: 0;
width: 100vw; height: 100vh;
z-index: -1;
overflow: hidden;
background-color: #000;
}

/* --- PROSE --- */

.prose-sleek h1 { font-size: 1.25rem; font-weight: 500; color: #fff; margin-bottom: 0.5rem; }
.prose-sleek h2 { font-size: 1rem; font-weight: 500; color: #fff; margin-top: 1rem; margin-bottom: 0.25rem; }
.prose-sleek p { font-size: 0.875rem; line-height: 1.7; color: rgba(255,255,255,0.75); }
.prose-sleek ul { list-style: disc; padding-left: 1.25rem; color: rgba(255,255,255,0.7); }
.prose-sleek li { font-size: 0.875rem; margin-bottom: 0.25rem; }
.prose-sleek strong { font-weight: 600; color: #fff; }

/* --- SCROLLBAR --- */

.custom-scrollbar::-webkit-scrollbar { width: 6px; }
.custom-scrollbar::-webkit-scrollbar-track { background: transparent; }
.custom-scrollbar::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.1); border-radius: 10px; }
.custom-scrollbar::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.2); }

/* --- CURSOR BLINK --- */

.cursor-blink { animation: blink 1s step-end infinite; }
@keyframes blink { 0%,100% { opacity: 1; } 50% { opacity: 0; } }
10 changes: 10 additions & 0 deletions kits/agentic/founder-lens/app/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading