Astralyte automates the entire research workflow using a coordinated chain of intelligent AI agents. A single topic input triggers a 4-stage pipeline—scouting, summarizing, analyzing, and synthesizing—to produce a concise, high-quality research brief.
- Kestra - Workflow Orchestration
- Cline - Agent-driven development and GitHub issue assistant
- CodeRabbit - PR reviews & code quality
- Next.js - Full-stack framework
- Vercel - Deployment
- Clone repository
git clone https://github.com/RakeshPotnuru/astralyte
cd astralyte- Install dependencies
pnpm i- Add environment variables
Create .env.local:
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY=
NEXT_PUBLIC_KESTRA_URL=
KESTRA_NAMESPACE=
KESTRA_WEBHOOK_KEY=
KESTRA_FLOW_ID=
NEXT_PUBLIC_BASE_URL=- Run development server
pnpm devYour app will be available at: http://localhost:3000
- Setup your Kestra instance (I recommend Docker Compose for local development)
- Create new flow and copy
kestra-flow.ymlto it. - Follow Kestra docs to create environment variables:
TAVILY_API_KEY=
GEMINI_API_KEY=
SUPABASE_URL=
SUPABASE_API_KEY=
WEBHOOK_KEY=- The Scout agent uses Tavily Web Search API to search for relevant web pages. So create a Tavily account and get an API key.
- Create new Supabase project
- Create new table with this query:
create table public.topics (
id uuid not null default gen_random_uuid (),
created_at timestamp with time zone not null default now(),
updated_at timestamp with time zone not null default now(),
user_id uuid not null default auth.uid (),
topic text not null,
agent_a_status public.agent_status not null default 'Not Started'::agent_status,
agent_a_output text null default 'Hunting for good stuff…'::text,
agent_b_status public.agent_status not null default 'Not Started'::agent_status,
agent_b_output text null default 'Shrinking the info…'::text,
agent_c_status public.agent_status not null default 'Not Started'::agent_status,
agent_c_output text null default 'Spotting patterns…'::text,
agent_d_status public.agent_status not null default 'Not Started'::agent_status,
agent_d_output text null default 'Packing it all together…'::text,
constraint topics_pkey primary key (id),
constraint topics_user_id_fkey foreign KEY (user_id) references auth.users (id) on delete CASCADE
) TABLESPACE pg_default;- Use this url for magic links:
{{ .RedirectTo }}?token_hash={{ .TokenHash }}&type=email
e.g: <p><a href="{{ .RedirectTo }}?token_hash={{ .TokenHash }}&type=email">Confirm your mail</a></p>
sequenceDiagram
participant User
participant Dashboard as Dashboard<br/>Component
participant API as Kestra<br/>Trigger API
participant Supabase as Supabase<br/>(Topics Table)
participant Kestra as Kestra<br/>Workflow
User->>Dashboard: Enter topic & click submit
Dashboard->>Supabase: Create topic record
Supabase-->>Dashboard: Return topic_id
Dashboard->>API: POST /api/trigger-kestra-flow<br/>{topic, topic_id}
API->>Kestra: Trigger workflow
Kestra->>Kestra: Run agents (A→B→C→D)
Kestra->>Supabase: update_agent_a_status<br/>(Pending)
Kestra->>Supabase: update_after_agent_a<br/>(Success, set B Pending)
Kestra->>Supabase: update_after_agent_b<br/>(Success, set C Pending)
Kestra->>Supabase: update_after_agent_c<br/>(Success, set D Pending)
Kestra->>Supabase: update_after_agent_d<br/>(Success)
Kestra-->>API: Workflow complete
API-->>Dashboard: Success response
Dashboard->>Supabase: Subscribe to topic updates
Supabase-->>Dashboard: Real-time updates as<br/>agents complete
Dashboard-->>User: Render agent outputs<br/>(A, B, C, D)
sequenceDiagram
participant User
participant Web as Web App<br/>(Next.js)
participant Supabase as Supabase<br/>(Auth & DB)
participant Email as Email Service
User->>Web: Opens app
Web->>Supabase: Check auth status
alt Unauthenticated
Supabase-->>Web: No user
Web-->>User: Show Auth page
User->>Web: Enter email
Web->>Supabase: signInWithOtp(email)
Supabase->>Email: Send OTP link
Email-->>User: OTP email
User->>Web: Click OTP link
Web->>Supabase: verifyOtp(token, type)
Supabase-->>Web: Auth session
Web-->>User: Redirect to /
else Authenticated
Supabase-->>Web: User data
Web-->>User: Show Dashboard
end
