-
Notifications
You must be signed in to change notification settings - Fork 92
Feat/resume fit #110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Feat/resume fit #110
Changes from all commits
3b51f8b
fe02306
8edae43
7614169
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| RESUME_FIT_FLOW="AGENTIC_GENERATE_CONTENT Flow ID" | ||
| LAMATIC_API_URL="LAMATIC_API_URL" | ||
| LAMATIC_PROJECT_ID="LAMATIC_PROJECT_ID" | ||
| LAMATIC_API_KEY="LAMATIC_API_KEY" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # 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* | ||
| !.env.example | ||
|
|
||
| # vercel | ||
| .vercel | ||
|
|
||
| # typescript | ||
| *.tsbuildinfo | ||
| next-env.d.ts |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| # Agent Kit Generation by Lamatic.ai | ||
|
|
||
| <p align="center"> | ||
| <a href="https://agent-kit-generation.vercel.app" target="_blank"> | ||
| <img src="https://img.shields.io/badge/Live%20Demo-black?style=for-the-badge" alt="Live Demo" /> | ||
| </a> | ||
| </p> | ||
|
|
||
|
|
||
| **Agent Kit Generation** is an AI-powered content generation system built with [Lamatic.ai](https://lamatic.ai). It uses intelligent workflows to generate text, images, and JSON content through a modern Next.js interface with markdown rendering support. | ||
|
|
||
| [](https://vercel.com/new/clone?repository-url=https://github.com/Lamatic/AgentKit&root-directory=kits/agentic/generation&env=AGENTIC_GENERATE_CONTENT,LAMATIC_API_URL,LAMATIC_PROJECT_ID,LAMATIC_API_KEY&envDescription=Your%20Lamatic%20Generation%20keys%20are%20required.&envLink=https://lamatic.ai/templates/agentkits/agentic/agent-kit-generation) | ||
|
Comment on lines
+1
to
+12
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agent, your cover story doesn't match your mission β this is a template from another operation! This README describes "Agent Kit Generation" but you're deploying "Resume Fit". The deploy button on line 12 points to Update all references:
π€ Prompt for AI Agents |
||
|
|
||
| --- | ||
|
|
||
| ## Lamatic Setup (Pre and Post) | ||
|
|
||
| Before running this project, you must build and deploy the flow in Lamatic, then wire its config into this codebase. | ||
|
|
||
| Pre: Build in Lamatic | ||
| 1. Sign in or sign up at https://lamatic.ai | ||
| 2. Create a project (if you donβt have one yet) | ||
| 3. Click β+ New Flowβ and select "Templates" | ||
| 4. Select the 'Generation' agent kit | ||
| 5. Configure providers/tools/inputs as prompted | ||
| 6. Deploy the kit in Lamatic and obtain your .env keys | ||
| 7. Copy the keys from your studio | ||
|
|
||
| Post: Wire into this repo | ||
| 1. Create a .env file and set the keys | ||
| 2. Install and run locally: | ||
| - npm install | ||
| - npm run dev | ||
| 3. Deploy (Vercel recommended): | ||
| - Import your repo, set the project's Root Directory (if applicable) | ||
| - Add env vars in Vercel (same as your .env) | ||
| - Deploy and test your live URL | ||
|
|
||
| Notes | ||
| - Coming soon: single-click export and "Connect Git" in Lamatic to push config directly to your repo. | ||
|
|
||
| --- | ||
|
|
||
| ## π Setup | ||
| ## Required Keys and Config | ||
|
Comment on lines
+44
to
+45
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor formatting issues flagged by static analysis. Lines 44-45 need blank lines around headings. Line 74 needs a blank line after the fenced code block. Line 79's code block should specify a language (e.g., Also applies to: 74-75, 79-79 π§° Toolsπͺ markdownlint-cli2 (0.22.0)[warning] 44-44: Headings should be surrounded by blank lines (MD022, blanks-around-headings) [warning] 45-45: Headings should be surrounded by blank lines (MD022, blanks-around-headings) π€ Prompt for AI Agents |
||
|
|
||
| Youβll need these things to run this project locally: | ||
|
|
||
| 1. **.env Keys** β get it from your [Lamatic account](https://lamatic.ai) post kit deployment. | ||
|
|
||
|
|
||
| | Item | Purpose | Where to Get It | | ||
| | ----------------- | -------------------------------------------- | ----------------------------------------------- | | ||
| | .env Key | Authentication for Lamatic AI APIs and Orchestration | [lamatic.ai](https://lamatic.ai) | | ||
|
|
||
| ### 1. Environment Variables | ||
|
|
||
| Create `.env.local` with: | ||
|
|
||
| ```bash | ||
| # Lamatic | ||
| AGENTIC_GENERATE_CONTENT = "AGENTIC_GENERATE_CONTENT Flow ID" | ||
| LAMATIC_API_URL = "LAMATIC_API_URL" | ||
| LAMATIC_PROJECT_ID = "LAMATIC_PROJECT_ID" | ||
| LAMATIC_API_KEY = "LAMATIC_API_KEY" | ||
| ``` | ||
|
Comment on lines
+60
to
+66
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Environment variable mismatch between documentation and configuration. The README documents π€ Prompt for AI Agents |
||
|
|
||
| ### 2. Install & Run | ||
|
|
||
| ```bash | ||
| npm install | ||
| npm run dev | ||
| # Open http://localhost:3000 | ||
| ``` | ||
| --- | ||
|
|
||
| ## π Repo Structure | ||
|
|
||
| ``` | ||
| /actions | ||
| βββ orchestrate.ts # Lamatic workflow orchestration | ||
| /app | ||
| βββ page.tsx # Main generation form UI | ||
| /components | ||
| βββ header.tsx # Header component with navigation | ||
| βββ ui # shadcn/ui components | ||
| /lib | ||
| βββ lamatic-client.ts # Lamatic SDK client | ||
| /public | ||
| βββ lamatic-logo.png # Lamatic branding | ||
| /flows | ||
| βββ ... # Lamatic Flows | ||
| /package.json # Dependencies & scripts | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## π€ Contributing | ||
|
|
||
| We welcome contributions! Open an issue or PR in this repo. | ||
|
|
||
| --- | ||
|
|
||
| ## π License | ||
|
|
||
| MIT License β see [LICENSE](../../../LICENSE). | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| export const config = { | ||
| flows: { | ||
| resumeFit: { | ||
| name: "Resume Fit Flow", | ||
| workflowId: process.env.AGENTIC_GENERATE_CONTENT, | ||
| inputSchema: { | ||
| instructions: "string", | ||
| mode: "string" | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+1
to
+12
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick | π΅ Trivial Agent, your config needs alignment with mission naming conventions. Two observations:
β»οΈ Suggested naming alignment export const config = {
flows: {
resumeFit: {
name: "Resume Fit Flow",
- workflowId: process.env.AGENTIC_GENERATE_CONTENT,
+ workflowId: process.env.RESUME_FIT_FLOW,
inputSchema: {
instructions: "string",
mode: "string"
}
}
}
}As per coding guidelines: "Kit server action files must call Lamatic flows via the SDK and read flow IDs from environment variables." π€ Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,128 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
| "use server" | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| import { lamaticClient } from "../lib/lamatic-client" | ||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π οΈ Refactor suggestion | π Major Agent, we have an unused asset in the field. The This message will self-destruct if you choose to accept this refactor: π§ Proposed mission parameters-import { lamaticClient } from "../lib/lamatic-client"
+// If SDK is required per guidelines, use lamaticClient here
+// Otherwise, remove this unused importBased on learnings: "Kit server action files (e.g., π€ Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||
| import { config } from "./config" | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| type InputType = "text" | "image" | "json" | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| export async function evaluateResume( | ||||||||||||||||||||||||||||||||||||||||||||||
| inputType: InputType, | ||||||||||||||||||||||||||||||||||||||||||||||
| instructions: string, | ||||||||||||||||||||||||||||||||||||||||||||||
| ): Promise<{ | ||||||||||||||||||||||||||||||||||||||||||||||
| success: boolean | ||||||||||||||||||||||||||||||||||||||||||||||
| data?: any | ||||||||||||||||||||||||||||||||||||||||||||||
| error?: string | ||||||||||||||||||||||||||||||||||||||||||||||
| }> { | ||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||
| console.log("[v0] Generating content with:", { inputType, instructions }) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // Get the first workflow from the config | ||||||||||||||||||||||||||||||||||||||||||||||
| const flows = config.flows | ||||||||||||||||||||||||||||||||||||||||||||||
| const firstFlowKey = Object.keys(flows)[0] | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| if (!firstFlowKey) { | ||||||||||||||||||||||||||||||||||||||||||||||
| throw new Error("No workflows found in configuration") | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // Fix: Add index signature to make TypeScript happy about accessing flows[firstFlowKey] | ||||||||||||||||||||||||||||||||||||||||||||||
| const flow = flows[firstFlowKey as keyof typeof flows] as (typeof flows)[keyof typeof flows]; | ||||||||||||||||||||||||||||||||||||||||||||||
| console.log("[v0] Using workflow:", flow.name, flow.workflowId); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // Prepare inputs based on the flow's input schema | ||||||||||||||||||||||||||||||||||||||||||||||
| const inputs: Record<string, any> = { | ||||||||||||||||||||||||||||||||||||||||||||||
| mode: inputType, | ||||||||||||||||||||||||||||||||||||||||||||||
| instructions, | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // Map to schema if needed | ||||||||||||||||||||||||||||||||||||||||||||||
| for (const inputKey of Object.keys(flow.inputSchema || {})) { | ||||||||||||||||||||||||||||||||||||||||||||||
| if (inputKey === "inputType" || inputKey === "type") { | ||||||||||||||||||||||||||||||||||||||||||||||
| inputs[inputKey] = inputType | ||||||||||||||||||||||||||||||||||||||||||||||
| } else if (inputKey === "instructions" || inputKey === "query") { | ||||||||||||||||||||||||||||||||||||||||||||||
| inputs[inputKey] = instructions | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| console.log("[v0] Sending inputs:", inputs) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| if(!flow.workflowId){ | ||||||||||||||||||||||||||||||||||||||||||||||
| throw Error("Workflow not found in config.") | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| const res = await fetch(process.env.LAMATIC_API_URL!, { | ||||||||||||||||||||||||||||||||||||||||||||||
| method: "POST", | ||||||||||||||||||||||||||||||||||||||||||||||
| headers: { | ||||||||||||||||||||||||||||||||||||||||||||||
| "Content-Type": "application/json", | ||||||||||||||||||||||||||||||||||||||||||||||
| "Authorization": `Bearer ${process.env.LAMATIC_API_KEY}`, | ||||||||||||||||||||||||||||||||||||||||||||||
| "x-project-id": process.env.LAMATIC_PROJECT_ID!, | ||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+51
to
+57
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical intel gap detected, agent. You're accessing environment variables with non-null assertions ( π‘οΈ Secure the perimeter+ const apiUrl = process.env.LAMATIC_API_URL
+ const apiKey = process.env.LAMATIC_API_KEY
+ const projectId = process.env.LAMATIC_PROJECT_ID
+
+ if (!apiUrl || !apiKey || !projectId) {
+ throw new Error("Missing required environment variables: LAMATIC_API_URL, LAMATIC_API_KEY, or LAMATIC_PROJECT_ID")
+ }
+
-const res = await fetch(process.env.LAMATIC_API_URL!, {
+const res = await fetch(apiUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
- "Authorization": `Bearer ${process.env.LAMATIC_API_KEY}`,
- "x-project-id": process.env.LAMATIC_PROJECT_ID!,
+ "Authorization": `Bearer ${apiKey}`,
+ "x-project-id": projectId,
},π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||
| body: JSON.stringify({ | ||||||||||||||||||||||||||||||||||||||||||||||
| query: ` | ||||||||||||||||||||||||||||||||||||||||||||||
| query ExecuteWorkflow($workflowId: String!, $payload: JSON!) { | ||||||||||||||||||||||||||||||||||||||||||||||
| executeWorkflow(workflowId: $workflowId, payload: $payload) { | ||||||||||||||||||||||||||||||||||||||||||||||
| status | ||||||||||||||||||||||||||||||||||||||||||||||
| result | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| `, | ||||||||||||||||||||||||||||||||||||||||||||||
| variables: { | ||||||||||||||||||||||||||||||||||||||||||||||
| workflowId: flow.workflowId, | ||||||||||||||||||||||||||||||||||||||||||||||
| payload: { | ||||||||||||||||||||||||||||||||||||||||||||||
| chatMessage: instructions, // π map your input here | ||||||||||||||||||||||||||||||||||||||||||||||
| mode: inputType, // optional depending on your flow | ||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| console.log("STATUS:", res.status) | ||||||||||||||||||||||||||||||||||||||||||||||
| console.log("CONTENT TYPE:", res.headers.get("content-type")) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| const resData = await res.json() | ||||||||||||||||||||||||||||||||||||||||||||||
| console.log("FULL RESPONSE:", JSON.stringify(resData, null, 2)) | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+77
to
+81
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick | π΅ Trivial Agent, your communications are compromised. These π΅οΈ Stealth mode recommended-console.log("STATUS:", res.status)
-console.log("CONTENT TYPE:", res.headers.get("content-type"))
-
- const resData = await res.json()
-console.log("FULL RESPONSE:", JSON.stringify(resData, null, 2))
+ const resData = await res.json()
+ // Consider structured logging for production observabilityπ Committable suggestion
Suggested change
π€ Prompt for AI Agents
Comment on lines
+80
to
+81
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mission abort condition not handled, agent. The fetch response status is logged but not validated. A non-2xx response will still proceed to π― Tactical improvement+if (!res.ok) {
+ throw new Error(`API request failed with status ${res.status}`)
+}
+
const resData = await res.json()
-console.log("FULL RESPONSE:", JSON.stringify(resData, null, 2))π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // Parse the answer from resData?.output.answer | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| const exec = resData?.data?.executeWorkflow | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| if (!exec) { | ||||||||||||||||||||||||||||||||||||||||||||||
| throw new Error("Invalid response structure") | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| if (exec.status !== "success") { | ||||||||||||||||||||||||||||||||||||||||||||||
| throw new Error("Workflow execution failed") | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // β FIX: extract content instead of answer | ||||||||||||||||||||||||||||||||||||||||||||||
| const answer = | ||||||||||||||||||||||||||||||||||||||||||||||
| exec?.result?.content || | ||||||||||||||||||||||||||||||||||||||||||||||
| exec?.result?.answer || // fallback if structure changes | ||||||||||||||||||||||||||||||||||||||||||||||
| exec?.result | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| if (!answer) { | ||||||||||||||||||||||||||||||||||||||||||||||
| throw new Error("No answer found in response") | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||
| success: true, | ||||||||||||||||||||||||||||||||||||||||||||||
| data: answer, | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||||||||||||||||||||||
| console.error("[v0] Generation error:", error) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| let errorMessage = "Unknown error occurred" | ||||||||||||||||||||||||||||||||||||||||||||||
| if (error instanceof Error) { | ||||||||||||||||||||||||||||||||||||||||||||||
| errorMessage = error.message | ||||||||||||||||||||||||||||||||||||||||||||||
| if (error.message.includes("fetch failed")) { | ||||||||||||||||||||||||||||||||||||||||||||||
| errorMessage = | ||||||||||||||||||||||||||||||||||||||||||||||
| "Network error: Unable to connect to the service. Please check your internet connection and try again." | ||||||||||||||||||||||||||||||||||||||||||||||
| } else if (error.message.includes("API key")) { | ||||||||||||||||||||||||||||||||||||||||||||||
| errorMessage = "Authentication error: Please check your API configuration." | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||
| success: false, | ||||||||||||||||||||||||||||||||||||||||||||||
| error: errorMessage, | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.