From 40f67990f92161870d65e53b52844bf2090eef3c Mon Sep 17 00:00:00 2001 From: Durvankur-joshi Date: Wed, 25 Mar 2026 16:54:05 +0530 Subject: [PATCH 01/11] feat: add AI Career Copilot AgentKit --- kits/assistant/ai-career-copilot/.env.example | 4 + kits/assistant/ai-career-copilot/.gitignore | 35 + kits/assistant/ai-career-copilot/README.md | 25 + .../ai-career-copilot/actions/orchestrate.ts | 87 + .../ai-career-copilot/app/globals.css | 27 + .../ai-career-copilot/app/layout.tsx | 29 + kits/assistant/ai-career-copilot/app/page.tsx | 95 + .../components/AnalysisResult.tsx | 87 + .../components/CareerAnalysisForm.tsx | 103 + .../components/ErrorMessage.tsx | 31 + .../components/InterviewQuestions.tsx | 31 + .../components/LoadingSpinner.tsx | 18 + .../components/ProjectsDisplay.tsx | 29 + .../components/RoadmapDisplay.tsx | 31 + .../components/SkillsDisplay.tsx | 49 + kits/assistant/ai-career-copilot/config.json | 28 + .../flows/ai-career-copilot/README.md | 63 + .../flows/ai-career-copilot/config.json | 397 ++ .../flows/ai-career-copilot/inputs.json | 146 + .../flows/ai-career-copilot/meta.json | 9 + kits/assistant/ai-career-copilot/git | 0 .../ai-career-copilot/lib/lamatic-client.ts | 56 + .../ai-career-copilot/next.config.js | 13 + kits/assistant/ai-career-copilot/package.json | 36 + .../ai-career-copilot/pnpm-lock.yaml | 4571 +++++++++++++++++ .../ai-career-copilot/postcss.config.js | 6 + .../ai-career-copilot/tailwind.config.ts | 43 + .../assistant/ai-career-copilot/tsconfig.json | 27 + .../ai-career-copilot/types/index.ts | 21 + 29 files changed, 6097 insertions(+) create mode 100644 kits/assistant/ai-career-copilot/.env.example create mode 100644 kits/assistant/ai-career-copilot/.gitignore create mode 100644 kits/assistant/ai-career-copilot/README.md create mode 100644 kits/assistant/ai-career-copilot/actions/orchestrate.ts create mode 100644 kits/assistant/ai-career-copilot/app/globals.css create mode 100644 kits/assistant/ai-career-copilot/app/layout.tsx create mode 100644 kits/assistant/ai-career-copilot/app/page.tsx create mode 100644 kits/assistant/ai-career-copilot/components/AnalysisResult.tsx create mode 100644 kits/assistant/ai-career-copilot/components/CareerAnalysisForm.tsx create mode 100644 kits/assistant/ai-career-copilot/components/ErrorMessage.tsx create mode 100644 kits/assistant/ai-career-copilot/components/InterviewQuestions.tsx create mode 100644 kits/assistant/ai-career-copilot/components/LoadingSpinner.tsx create mode 100644 kits/assistant/ai-career-copilot/components/ProjectsDisplay.tsx create mode 100644 kits/assistant/ai-career-copilot/components/RoadmapDisplay.tsx create mode 100644 kits/assistant/ai-career-copilot/components/SkillsDisplay.tsx create mode 100644 kits/assistant/ai-career-copilot/config.json create mode 100644 kits/assistant/ai-career-copilot/flows/ai-career-copilot/README.md create mode 100644 kits/assistant/ai-career-copilot/flows/ai-career-copilot/config.json create mode 100644 kits/assistant/ai-career-copilot/flows/ai-career-copilot/inputs.json create mode 100644 kits/assistant/ai-career-copilot/flows/ai-career-copilot/meta.json create mode 100644 kits/assistant/ai-career-copilot/git create mode 100644 kits/assistant/ai-career-copilot/lib/lamatic-client.ts create mode 100644 kits/assistant/ai-career-copilot/next.config.js create mode 100644 kits/assistant/ai-career-copilot/package.json create mode 100644 kits/assistant/ai-career-copilot/pnpm-lock.yaml create mode 100644 kits/assistant/ai-career-copilot/postcss.config.js create mode 100644 kits/assistant/ai-career-copilot/tailwind.config.ts create mode 100644 kits/assistant/ai-career-copilot/tsconfig.json create mode 100644 kits/assistant/ai-career-copilot/types/index.ts diff --git a/kits/assistant/ai-career-copilot/.env.example b/kits/assistant/ai-career-copilot/.env.example new file mode 100644 index 00000000..44212670 --- /dev/null +++ b/kits/assistant/ai-career-copilot/.env.example @@ -0,0 +1,4 @@ +AGENTIC_GENERATE_CONTENT=your-flow-id +LAMATIC_API_URL=https://your-project.lamatic.dev/graphql +LAMATIC_PROJECT_ID=your-project-id +LAMATIC_API_KEY=your-api-key \ No newline at end of file diff --git a/kits/assistant/ai-career-copilot/.gitignore b/kits/assistant/ai-career-copilot/.gitignore new file mode 100644 index 00000000..bce9269b --- /dev/null +++ b/kits/assistant/ai-career-copilot/.gitignore @@ -0,0 +1,35 @@ +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local +.env + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts \ No newline at end of file diff --git a/kits/assistant/ai-career-copilot/README.md b/kits/assistant/ai-career-copilot/README.md new file mode 100644 index 00000000..0ab0e7f4 --- /dev/null +++ b/kits/assistant/ai-career-copilot/README.md @@ -0,0 +1,25 @@ +# AI Career Copilot + +An AI-powered career assistant that analyzes resumes and provides personalized career guidance including skill analysis, job recommendations, learning roadmaps, project suggestions, and interview preparation. + +## Features + +- 🎯 **Skill Analysis**: Automatically extract and analyze skills from resumes +- πŸ“Š **Readiness Score**: Get a score indicating career readiness for target domains +- πŸ’Ό **Job Role Recommendations**: Discover suitable job roles based on your skills +- πŸ—ΊοΈ **Learning Roadmap**: Get a step-by-step learning path to fill skill gaps +- πŸš€ **Project Suggestions**: Practical projects to build portfolio and skills +- πŸ’¬ **Interview Questions**: Practice questions tailored to your target role + +## Prerequisites + +- Node.js 18+ and npm +- Lamatic.ai account with API access +- Lamatic flow exported (included in `flows/` directory) + +## Installation + +1. Clone the repository: +```bash +git clone https://github.com/yourusername/ai-career-copilot.git +cd ai-career-copilot \ No newline at end of file diff --git a/kits/assistant/ai-career-copilot/actions/orchestrate.ts b/kits/assistant/ai-career-copilot/actions/orchestrate.ts new file mode 100644 index 00000000..0bf6b07f --- /dev/null +++ b/kits/assistant/ai-career-copilot/actions/orchestrate.ts @@ -0,0 +1,87 @@ +'use server'; + +import { lamaticClient } from '@/lib/lamatic-client'; +import { CareerAnalysisInput, CareerAnalysisOutput, ApiResponse } from '@/types'; + +export async function analyzeCareer( + input: CareerAnalysisInput +): Promise { + try { + console.log('πŸš€ Analyzing career with input:', { + resumeLength: input.resume_text?.length, + domain: input.domain + }); + + // Validate input + if (!input.resume_text || input.resume_text.trim().length === 0) { + return { + success: false, + error: 'Resume text is required', + }; + } + + if (!input.domain || input.domain.trim().length === 0) { + return { + success: false, + error: 'Target domain is required', + }; + } + + let result; + let lastError; + + // Try the main mutation first + try { + console.log('πŸ“‘ Trying main GraphQL mutation...'); + result = await lamaticClient.executeCareerAnalysis({ + resume_text: input.resume_text, + domain: input.domain, + }); + console.log('βœ… Main mutation succeeded!'); + } catch (error) { + lastError = error; + console.log('⚠️ Main mutation failed, trying alternative...'); + + // Try alternative mutation + try { + result = await lamaticClient.executeAlternativeMutation({ + resume_text: input.resume_text, + domain: input.domain, + }); + console.log('βœ… Alternative mutation succeeded!'); + } catch (altError) { + console.log('⚠️ Alternative mutation failed, trying specific mutation...'); + + // Try specific mutation + try { + result = await lamaticClient.executeWithSpecificMutation({ + resume_text: input.resume_text, + domain: input.domain, + }); + console.log('βœ… Specific mutation succeeded!'); + } catch (specificError) { + console.error('❌ All mutations failed'); + throw lastError; + } + } + } + + return { + success: true, + data: result, + timestamp: new Date().toISOString(), + }; + } catch (error) { + console.error('❌ Career analysis error:', error); + + let errorMessage = 'Failed to analyze career data. Please check your configuration.'; + if (error instanceof Error) { + errorMessage = error.message; + } + + return { + success: false, + error: errorMessage, + }; + } +} \ No newline at end of file diff --git a/kits/assistant/ai-career-copilot/app/globals.css b/kits/assistant/ai-career-copilot/app/globals.css new file mode 100644 index 00000000..1443a2af --- /dev/null +++ b/kits/assistant/ai-career-copilot/app/globals.css @@ -0,0 +1,27 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + body { + @apply bg-gray-50 text-gray-900; + } +} + +@layer components { + .btn-primary { + @apply bg-primary-600 text-white px-6 py-2 rounded-lg hover:bg-primary-700 transition-colors duration-200 font-medium; + } + + .btn-secondary { + @apply bg-gray-200 text-gray-800 px-6 py-2 rounded-lg hover:bg-gray-300 transition-colors duration-200 font-medium; + } + + .card { + @apply bg-white rounded-xl shadow-md p-6 border border-gray-100; + } + + .input-field { + @apply w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent outline-none transition; + } +} \ No newline at end of file diff --git a/kits/assistant/ai-career-copilot/app/layout.tsx b/kits/assistant/ai-career-copilot/app/layout.tsx new file mode 100644 index 00000000..448f770c --- /dev/null +++ b/kits/assistant/ai-career-copilot/app/layout.tsx @@ -0,0 +1,29 @@ +import type { Metadata } from 'next'; +import { Inter } from 'next/font/google'; +import './globals.css'; + +const inter = Inter({ subsets: ['latin'] }); + +export const metadata: Metadata = { + title: 'AI Career Copilot | Your Personal Career Assistant', + description: 'AI-powered career analysis tool that helps you identify skills, find suitable roles, and create personalized learning paths.', + keywords: 'career, AI, resume analysis, job recommendations, skill development, career planning', + authors: [{ name: 'Your Name' }], + openGraph: { + title: 'AI Career Copilot', + description: 'Your personal AI career assistant', + type: 'website', + }, +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} \ No newline at end of file diff --git a/kits/assistant/ai-career-copilot/app/page.tsx b/kits/assistant/ai-career-copilot/app/page.tsx new file mode 100644 index 00000000..72e1b058 --- /dev/null +++ b/kits/assistant/ai-career-copilot/app/page.tsx @@ -0,0 +1,95 @@ +'use client'; + +import { useState } from 'react'; +import { analyzeCareer } from '@/actions/orchestrate'; +import CareerAnalysisForm from '@/components/CareerAnalysisForm'; +import AnalysisResult from '@/components/AnalysisResult'; +import LoadingSpinner from '@/components/LoadingSpinner'; +import ErrorMessage from '@/components/ErrorMessage'; +import { CareerAnalysisOutput } from '@/types'; + +export default function Home() { + const [loading, setLoading] = useState(false); + const [result, setResult] = useState(null); + const [error, setError] = useState(null); + + const handleAnalyze = async (resumeText: string, domain: string) => { + setLoading(true); + setError(null); + + try { + const response = await analyzeCareer({ + resume_text: resumeText, + domain: domain, + }); + + if (response.success && response.data) { + setResult(response.data); + } else { + setError(response.error || 'Failed to analyze career data'); + } + } catch (err) { + setError(err instanceof Error ? err.message : 'An unexpected error occurred'); + } finally { + setLoading(false); + } + }; + + const handleReset = () => { + setResult(null); + setError(null); + }; + + return ( +
+
+ {/* Header */} +
+

+ AI Career Copilot +

+

+ Your personal AI-powered career assistant. Get personalized insights, + skill analysis, and a complete roadmap to achieve your career goals. +

+
+ + {/* Main Content */} +
+ {!result && !loading && ( + + )} + + {loading && ( +
+ +
+ )} + + {error && ( + window.location.reload()} /> + )} + + {result && !loading && !error && ( + <> + +
+ +
+ + )} +
+ + {/* Footer */} +
+

Powered by Lamatic.ai - AI Career Assistant

+
+
+
+ ); +} \ No newline at end of file diff --git a/kits/assistant/ai-career-copilot/components/AnalysisResult.tsx b/kits/assistant/ai-career-copilot/components/AnalysisResult.tsx new file mode 100644 index 00000000..dde95dbc --- /dev/null +++ b/kits/assistant/ai-career-copilot/components/AnalysisResult.tsx @@ -0,0 +1,87 @@ +'use client'; + +import { CareerAnalysisOutput } from '@/types'; +import SkillsDisplay from './SkillsDisplay'; +import RoadmapDisplay from './RoadmapDisplay'; +import ProjectsDisplay from './ProjectsDisplay'; +import InterviewQuestions from './InterviewQuestions'; +import { TrendingUp, Briefcase, Lightbulb } from 'lucide-react'; + +interface AnalysisResultProps { + data: CareerAnalysisOutput; +} + +export default function AnalysisResult({ data }: AnalysisResultProps) { + const getScoreColor = (score: number) => { + if (score >= 80) return 'text-green-600'; + if (score >= 60) return 'text-yellow-600'; + return 'text-red-600'; + }; + + const getScoreLevel = (score: number) => { + if (score >= 80) return 'Excellent - Ready for opportunities!'; + if (score >= 60) return 'Good - Getting there!'; + if (score >= 40) return 'Fair - Some work needed'; + return 'Needs Improvement - Focus on skill development'; + }; + + return ( +
+ {/* Readiness Score Card */} +
+
+
+

+ + Career Readiness Score +

+

+ {data.readiness_score}/100 +

+

+ {getScoreLevel(data.readiness_score)} +

+
+
+

+ Based on your current skills vs required skills +

+
+
+
+ + {/* Skills Analysis */} + + + {/* Recommended Roles */} +
+

+ + Recommended Job Roles +

+
+ {data.roles.map((role, idx) => ( + + {role} + + ))} +
+
+ + {/* Learning Roadmap */} + + + {/* Project Suggestions */} + + + {/* Interview Questions */} + +
+ ); +} \ No newline at end of file diff --git a/kits/assistant/ai-career-copilot/components/CareerAnalysisForm.tsx b/kits/assistant/ai-career-copilot/components/CareerAnalysisForm.tsx new file mode 100644 index 00000000..54abdffb --- /dev/null +++ b/kits/assistant/ai-career-copilot/components/CareerAnalysisForm.tsx @@ -0,0 +1,103 @@ +'use client'; + +import { useState } from 'react'; + +interface CareerAnalysisFormProps { + onSubmit: (resumeText: string, domain: string) => void; +} + +const DOMAINS = [ + 'Frontend Development', + 'Backend Development', + 'Full Stack Development', + 'Data Science', + 'Machine Learning', + 'DevOps', + 'Mobile Development', + 'Cloud Architecture', + 'Cybersecurity', + 'Product Management', + 'UI/UX Design', + 'Quality Assurance', +]; + +export default function CareerAnalysisForm({ onSubmit }: CareerAnalysisFormProps) { + const [resumeText, setResumeText] = useState(''); + const [domain, setDomain] = useState(''); + const [errors, setErrors] = useState<{ resumeText?: string; domain?: string }>({}); + + const validate = () => { + const newErrors: { resumeText?: string; domain?: string } = {}; + + if (!resumeText.trim()) { + newErrors.resumeText = 'Please paste your resume text'; + } else if (resumeText.trim().length < 50) { + newErrors.resumeText = 'Please provide at least 50 characters of resume text for accurate analysis'; + } + + if (!domain) { + newErrors.domain = 'Please select your target domain'; + } + + setErrors(newErrors); + return Object.keys(newErrors).length === 0; + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (validate()) { + onSubmit(resumeText, domain); + } + }; + + return ( +
+

Career Analysis

+
+
+ +