Skip to content

feat: groq api#465

Open
madsysharma wants to merge 10 commits into
AditthyaSS:mainfrom
madsysharma:feat/groq-support
Open

feat: groq api#465
madsysharma wants to merge 10 commits into
AditthyaSS:mainfrom
madsysharma:feat/groq-support

Conversation

@madsysharma

@madsysharma madsysharma commented Jun 4, 2026

Copy link
Copy Markdown

feat: Groq API

Closes #284

Summary

Adds Groq as a runtime-selectable LLM provider alongside OpenAI, Anthropic and Gemini.
Groq exposes an OpenAI-compatible Chat Completions endpoint, so this slots cleanly into the existing unified adapter architecture with no new runtime dependencies and no backend changes: keys still go directly from the browser to the provider.
This makes the platform more accessible to students, beginners, and GSSoC contributors: Groq offers rapid LPU inference, a generous free tier and powerful open-weight models at little to no cost.

What changed

Area File Change
Adapter src/lib/llmAdapter.js New groq entry in PROVIDER_CONFIGS: endpoint https://api.groq.com/openai/v1/chat/completions, Bearer auth, OpenAI-shaped request/response, and SSE streaming. Supports both runAgent (one-shot) and streamAgent (streaming). JSDoc provider unions updated.
Models src/lib/resolveAgentModel.js Added MODELS.groq (curated current production models) and MODEL_MAP.groq default (llama-3.3-70b-versatile). resolveAgentModel now resolves and falls back correctly for Groq.
Provider bar src/components/ApiKeyBar.jsx Groq added to PROVIDERS, providerLogos, and providerUrls (key page: console.groq.com/keys); new Alt+4 quick-switch shortcut.
Runner src/components/AgentRunner.jsx providerLabels.groq label + a dedicated invalid-API-key error message for Groq.
Asset src/assets/groq.svg New original provider icon (Groq brand orange), sized to scale in the 16×16 logo slot.
Tests tests/groq-provider.test.js Dependency-free smoke suite (Node's built-in runner) exercising the real exported functions through the Groq path.
Scripts package.json Added npm test -> node --test "tests/**/*.test.js".
Docs README.md, CHANGELOG.md Documented Groq in the providers table, the "why" list, the agent-schema comment, and a Keep-a-Changelog Unreleased entry.

Models included

Curated to current Groq production models (the issue's suggested mixtral-8x7b-32768 has since been decommissioned on GroqCloud, so it was intentionally omitted):

  • llama-3.3-70b-versatile: Llama 3.3 70B Versatile (default)
  • llama-3.1-8b-instant: Llama 3.1 8B Instant
  • openai/gpt-oss-120b: GPT-OSS 120B
  • openai/gpt-oss-20b: GPT-OSS 20B
    These mirror the static, curated-list convention already used for OpenAI and Anthropic.

Design notes

  • Reuses the existing provider architecture exactly as the issue suggested. Since Groq is OpenAI-compatible, the adapter config closely follows the existing openrouter/openai shape (system + user messages, max_tokens, stream, choices[].delta.content SSE parsing, data: [DONE] terminator).
  • No new dependencies, no .env, no backend. Consistent with the project's "bring your own key, runs in the browser" model.
  • Battle Mode is intentionally out of scope. BattleModeArena / BattleModeSetup are a hard-coded 3-way comparison (OpenAI vs Anthropic vs Gemini) whose UI assumes exactly three color-coded columns. Adding a fourth provider there is a separate, larger change and isn't what this issue targets ("API Key / Provider Bar"). Happy to follow up in a dedicated PR if maintainers want it.

Testing

Automated

PS C:\Users\madhu\Documents\iloveAgents> npm test

> i-love-agents@1.0.0 test
> node --test "tests/**/*.test.js"

✔ MODELS includes a non-empty groq list (3.8119ms)
✔ groq default model is the first listed and is a current production model (0.3773ms)
✔ resolveAgentModel honors a valid groq model and falls back to the groq default (0.505ms)
✔ runAgent(groq) calls the OpenAI-compatible endpoint with Bearer auth and parses the response (2.3725ms)
✔ runAgent(groq) maps a 401 to an invalid_api_key error tagged with provider (2.7914ms)
✔ runAgent rejects an empty API key before hitting the network (0.7485ms)
✔ streamAgent(groq) parses OpenAI-style SSE chunks and concatenates content (2.5552ms)
ℹ tests 7
ℹ suites 0
ℹ pass 7
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 255.6991

Manual

  1. npm run dev
  2. Open any agent; in the provider bar choose Groq (or press Alt+4).
  3. Verify the Groq logo renders and the model dropdown lists the four Groq models.
  4. Paste a key from https://console.groq.com/keys and run an agent -> fast streamed output.
  5. Enter an invalid key -> "Your Groq API key is invalid or expired." appears.
  6. Tick Save for session, reload, confirm the key persists; switch providers and confirm models swap correctly.

Demo

Normal run:

Screen.Recording.2026-06-04.135124.-.Trim.mp4

Trying to run with invalid/expired API key:

Screen.Recording.2026-06-04.135252.mp4

Save for session:

Screen.Recording.2026-06-04.135440.mp4

Notes for reviewers

  • The provider icon in src/assets/groq.svg is an original mark in Groq's brand color (not a copy of Groq's proprietary logo artwork). If maintainers prefer the official brand SVG, it's a one-line swap.
  • The npm run build step currently fails on main due to a pre-existing, unrelated default-export mismatch between src/agents/registry.js (exports loadAllAgents) and components importing agents as a default (e.g. Sidebar.jsx). That is not introduced by this PR and is left untouched. All files changed here transform cleanly through esbuild/Vite.

Checklist

  • Created a feature branch (e.g. feature/groq-provider)
  • Reuses existing provider architecture
  • Provider selectable at runtime like OpenAI/Gemini
  • One-shot and streaming supported
  • Curated, current, non-deprecated models
  • Invalid-key handling + key-page link
  • Tests added and passing
  • Docs + changelog updated
  • No new dependencies; key never leaves the browser

Summary by CodeRabbit

  • New Features
    • Groq added as a selectable AI provider with curated production models, one-shot and streaming responses, provider logo, and Alt+4 quick-switch (also shown in keyboard shortcuts).
  • Bug Fixes
    • Improved invalid API key handling with Groq-specific error messaging.
  • Documentation
    • README and changelog updated to list Groq and supported models.
  • Tests
    • New Node test suite validating Groq provider behavior and streaming.

@madsysharma madsysharma requested a review from AditthyaSS as a code owner June 4, 2026 21:12
@vercel

vercel Bot commented Jun 4, 2026

Copy link
Copy Markdown

@madsysharma is attempting to deploy a commit to the aditthyass' projects Team on Vercel.

A member of the Team first needs to authorize it.

@mergify

mergify Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

hey @madsysharma! 👋
Your PR title doesn't follow our required format.
Please update it to:
type: short description
Valid types: feat, fix, docs, style, refactor, test, chore
Example: feat: add sales discovery agent
@AditthyaSS

@mergify mergify Bot added the needs-fix label Jun 4, 2026
@madsysharma madsysharma changed the title Feat/groq support Feat: groq support Jun 4, 2026
@madsysharma madsysharma changed the title Feat: groq support feat: groq api Jun 4, 2026
@madsysharma

madsysharma commented Jun 4, 2026

Copy link
Copy Markdown
Author

Hi @AditthyaSS , please review this PR. Thanks. Also, please add the gssoc:approved label to it if everything is good to go. Thank you.

@mergify

mergify Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

⚠️ Hey @madsysharma! This PR has a merge conflict that needs to be resolved before we can review or merge it.
Please sync your branch with the latest main and fix the conflicts.
Need help? Check out resolving merge conflicts.
@AditthyaSS

@AditthyaSS

Copy link
Copy Markdown
Owner

@madsysharma I can see there are merge conflicts...

@madsysharma

Copy link
Copy Markdown
Author

Hi @AditthyaSS , have resolved the merge conflicts. Please check.

@mergify

mergify Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

⚠️ This branch is out of date with main.
Please click "Update branch" to sync before merging.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key: "issues"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Walkthrough

Adds Groq as a supported AI provider: model registry and defaults, OpenAI-compatible adapter (one-shot + SSE streaming), UI wiring (logo, label, Alt+4, error messaging), agent-hook integrations across pages, a Node test suite, and docs/package manifest updates.

Changes

Groq Provider Integration

Layer / File(s) Summary
Provider model registry and JSDoc types
src/lib/resolveAgentModel.js, src/lib/llmAdapter.js
Groq models are registered in MODELS and MODEL_MAP for default selection; top-of-file docs and JSDoc unions for runAgent and streamAgent are updated to include 'groq'.
Core Groq adapter implementation
src/lib/llmAdapter.js
PROVIDER_CONFIGS is extended with a groq entry that defines the OpenAI-compatible endpoint, request/response builders, and SSE streaming SSE chunk parsing logic.
UI component integration
src/components/ApiKeyBar.jsx, src/components/AgentRunner.jsx, src/components/KeyboardShortcutsModal.jsx
Groq is added to provider selection with logo import, providerLogos/providerUrls mappings, keyboard shortcut Alt+4, display label mapping, and Groq-specific invalid API key error messaging.
Battle mode provider support
src/pages/BattleModeSetup.jsx
Groq provider configuration is added to PROVIDERS array with display label, model id, and UI styling classes; other per-provider rendering remains unchanged.
Agent registry hook integration
src/pages/HomePage.jsx, src/pages/WorkflowBuilder.jsx, src/pages/WorkflowRunner.jsx
useAgents hook is integrated in pages; HomePage memos now depend on agents; WorkflowBuilder seeds selectedAgents from preselected IDs once agents load; WorkflowRunner imports useAgents.
Comprehensive Groq provider test suite
tests/groq-provider.test.js
Node.js test file validates model registry shape, model resolution fallback, one-shot request format and token counting, 401->invalid_api_key mapping, API key validation, and OpenAI-compatible SSE streaming with delta aggregation.
Documentation and manifest updates
CHANGELOG.md, README.md, package.json
CHANGELOG documents Groq feature and shortcut; README adds Groq to provider list and supported models table; package.json adds a test script running node --test "tests/**/*.test.js".

Sequence Diagram (high-level request flow):

sequenceDiagram
  participant App
  participant llmAdapter
  participant GroqAPI
  App->>llmAdapter: call runAgent/streamAgent(provider='groq', model, key)
  llmAdapter->>GroqAPI: POST /openai/v1/chat/completions (Bearer key, JSON body)
  GroqAPI-->>llmAdapter: HTTP response or SSE frames (delta.content / [DONE])
  llmAdapter-->>App: parsed content, tokens, duration or error
Loading

Estimated code review effort:
🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels:
level:intermediate

Suggested reviewers:

  • AditthyaSS
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'feat: groq api' is vague and lacks specificity about what aspect of Groq API support is being added. Consider a more descriptive title like 'feat: add Groq as LLM provider with OpenAI-compatible endpoint' to better convey the scope.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The PR comprehensively implements all coding requirements from issue #284: adds Groq provider selection in UI, leverages OpenAI-compatible endpoint for adapter, provides curated models with defaults, and maintains the existing architecture.
Out of Scope Changes check ✅ Passed All changes are in-scope for adding Groq provider support. The only noted out-of-scope item (Battle Mode changes) appears intentionally deferred per PR objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
src/pages/WorkflowBuilder.jsx (1)

68-80: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Critical: setNodes and setEdges are undefined — runtime crash.

Lines 70 and 74 call setNodes() and setEdges() but these state setters are never declared in this component. The component only has selectedAgents, title, description, etc. as state variables.

This appears to be code from a different node-based workflow editor that was incorrectly merged or copied here.

🐛 Proposed fix: Use existing state or remove dead code

If forking should populate the agent chain, use the existing selectedAgents state:

   // Pre-populate from forked workflow
   useEffect(() => {
-  if (forkedWorkflow) {
-    setNodes(
-      JSON.parse(JSON.stringify(forkedWorkflow.nodes || []))
-    )
-
-    setEdges(
-      JSON.parse(JSON.stringify(forkedWorkflow.edges || []))
-    )
-
-    setTitle(`Copy of ${forkedWorkflow.title}`)
-  }
+    if (forkedWorkflow) {
+      // Resolve agent IDs to agent objects once registry loads
+      if (agents.length && forkedWorkflow.agents?.length) {
+        const loaded = forkedWorkflow.agents
+          .map((id) => agents.find((a) => a.id === id))
+          .filter(Boolean)
+        setSelectedAgents(loaded)
+      }
+      setTitle(`Copy of ${forkedWorkflow.title}`)
+      setDescription(forkedWorkflow.description || '')
+    }
+  }, [forkedWorkflow, agents])
-}, [forkedWorkflow])
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/WorkflowBuilder.jsx` around lines 68 - 80, The effect references
undefined setters setNodes and setEdges (causing the crash); replace that logic
to populate the existing agent chain state instead or remove it: inside the
useEffect that checks forkedWorkflow, call
setSelectedAgents(JSON.parse(JSON.stringify(forkedWorkflow.agents || []))) to
copy agents from forkedWorkflow (or map forkedWorkflow.nodes -> agents if agents
are stored in nodes), keep the setTitle(`Copy of ${forkedWorkflow.title}`) line,
and remove any setNodes/setEdges calls; ensure forkedWorkflow structure matches
(agents vs nodes/edges) and adjust the mapping accordingly.
src/pages/HomePage.jsx (1)

31-48: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Critical: Missing import and duplicate declarations will cause runtime errors.

Multiple issues in this code segment:

  1. useAgents is called on line 31 but is never imported — this will throw a ReferenceError at runtime.
  2. agents is declared twice: from useAgents() (line 31) and from useState([]) (line 33) — JavaScript will throw a syntax error for redeclaring a const.
  3. allCategories is declared twice (lines 39-41 and lines 44-48) — another redeclaration error.

This appears to be an incomplete refactor where both the old local-state approach and the new useAgents hook exist simultaneously. Choose one approach and remove the other.

🐛 Proposed fix: Use useAgents hook exclusively

Add the missing import at the top of the file:

 import { useState, useMemo, useEffect } from 'react'
 import { useNavigate } from 'react-router-dom'
+import { useAgents } from '../lib/useAgents'

Then remove the duplicate declarations and legacy loading logic:

 export default function HomePage() {
   const navigate = useNavigate()
   const { agents } = useAgents()
   const [searchQuery, setSearchQuery] = useState('')
-  const [agents, setAgents] = useState([])
-
-useEffect(() => {
-  loadAllAgents().then(setAgents)
-}, [])
   const [selectedCategory, setSelectedCategory] = useState(null)
-  const allCategories = useMemo(() => {
-    return [...new Set(agents.map((a) => a.category))].sort()
-  }, [agents])
   useDocumentTitle()

   // Derive unique sorted categories from the loaded registry
   const allCategories = useMemo(
     () => [...new Set(agents.map((a) => a.category))].sort(),
     [agents]
   )

Also remove the now-unused loadAllAgents import if fully migrating to the hook.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/HomePage.jsx` around lines 31 - 48, Import the useAgents hook at
the top of the file and migrate to using it exclusively: remove the local agents
useState([]), the setAgents reference and the useEffect that calls
loadAllAgents(), and remove the loadAllAgents import if no longer used; also
delete the duplicate allCategories declaration so only the useMemo that derives
categories from agents (from useAgents()) remains; ensure any references use the
hook's agents value and keep useDocumentTitle as-is.
src/pages/BattleModeSetup.jsx (2)

95-106: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Critical: State initialization missing groq entry.

The PROVIDERS array now includes groq (lines 60-72), but the initial state for results and prompts only includes openai, anthropic, and gemini. This creates an inconsistency where:

  1. The PROVIDERS.forEach loop at line 123 will iterate over groq and attempt to update results.groq and prompts.groq
  2. The rendering loop at line 376 will access results[prov.id] for groq, which will be undefined initially
  3. During the initial render before the useEffect runs, the groq card will display with undefined state

This will cause runtime errors or unexpected behavior.

🔧 Proposed fix to include groq in state initialization
 const [results, setResults] = useState({
   openai: { loading: true, content: null, error: null, duration: null },
   anthropic: { loading: true, content: null, error: null, duration: null },
   gemini: { loading: true, content: null, error: null, duration: null },
+  groq: { loading: true, content: null, error: null, duration: null },
 });

 const [promptViewerOpen, setPromptViewerOpen] = useState(false);
 const [prompts, setPrompts] = useState({
   openai: null,
   anthropic: null,
   gemini: null,
+  groq: null,
 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/BattleModeSetup.jsx` around lines 95 - 106, The initial state for
results and prompts is missing an entry for the new provider "groq", causing
undefined access when PROVIDERS.forEach updates results.groq and rendering reads
results[prov.id]; update the useState initializers for results and prompts in
BattleModeSetup (the const [results, setResults] = useState(...) and const
[prompts, setPrompts] = useState(...)) to include a groq key mirroring the shape
of the other providers (e.g., results.groq: { loading: true, content: null,
error: null, duration: null } and prompts.groq: null) so PROVIDERS.forEach and
the render loop can safely access results[prov.id] and prompts[prov.id].

214-372: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Major: Prompt viewer hardcodes 3 providers, excludes Groq.

The Prompt Comparison Viewer (lines 230-372) hardcodes three separate columns for OpenAI, Claude, and Gemini, but doesn't include a column for Groq despite Groq being added to the PROVIDERS array. This means:

  1. When users run battle mode with Groq, they won't be able to view the Groq prompt in the comparison viewer
  2. The UI is inconsistent with the available providers

Either dynamically render columns based on the PROVIDERS array, or explicitly add a fourth column for Groq.

📋 Recommended approach

Consider refactoring the prompt viewer to dynamically render columns based on PROVIDERS:

{promptViewerOpen && (
  <div className="mt-4 battle-fade-in">
    <div className="grid grid-cols-1 lg:grid-cols-3 xl:grid-cols-4 gap-6">
      {PROVIDERS.map((prov) => (
        <div key={prov.id} className="rounded-xl border border-gray-800 bg-gray-900/30 backdrop-blur-sm flex flex-col overflow-hidden">
          <div className={`bg-gray-900/50 border-b border-gray-800 px-4 py-3 flex items-center justify-between`}>
            <span className={`text-sm font-bold ${prov.textColor}`}>
              {prov.label}
            </span>
            <button
              onClick={() => handleCopyPrompt(prov.id, prompts[prov.id])}
              className="flex items-center gap-1.5 px-2 py-1 rounded-md hover:bg-gray-800/50 transition-all duration-200"
            >
              {copiedProvider === prov.id ? (
                <>
                  <Check size={14} className="text-green-400" />
                  <span className="text-xs text-green-400">Copied</span>
                </>
              ) : (
                <Copy size={14} className="text-gray-400 hover:text-gray-300" />
              )}
            </button>
          </div>
          {/* Render system and user prompts */}
        </div>
      ))}
    </div>
  </div>
)}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/BattleModeSetup.jsx` around lines 214 - 372, The Prompt Comparison
Viewer currently hardcodes OpenAI/Claude/Gemini columns and omits Groq; update
it to render provider columns dynamically from the PROVIDERS array (or add an
explicit Groq column) so all providers (including "groq") appear. In practice,
replace the three hardcoded blocks with a map over PROVIDERS (use provider.id,
provider.label, provider.textColor) to produce each column, call
handleCopyPrompt(provider.id, prompts[provider.id]) for the copy button, and use
copiedProvider === provider.id to toggle the Check/Copy UI; also adjust the grid
classes (e.g., lg:grid-cols-3 xl:grid-cols-4) to accommodate the extra column.
🧹 Nitpick comments (1)
src/lib/llmAdapter.js (1)

101-144: ⚡ Quick win

Consider extracting a shared helper for OpenAI-compatible provider configs.

The groq configuration is identical to openai (and very similar to openrouter) except for the endpoint URL. With three providers now sharing this OpenAI-compatible format, extracting a helper function would reduce duplication and improve maintainability. Bug fixes or improvements to the parsing logic would then apply consistently across all OpenAI-compatible providers.

♻️ Example refactoring approach
+// Helper for OpenAI-compatible endpoints (OpenAI, OpenRouter, Groq, etc.)
+function createOpenAICompatibleConfig(url, additionalHeaders = {}) {
+  return {
+    url,
+    buildHeaders: (apiKey) => ({
+      'Content-Type': 'application/json',
+      Authorization: `Bearer ${apiKey}`,
+      ...additionalHeaders,
+    }),
+    buildBody: (model, systemPrompt, userMessage) => ({
+      model,
+      messages: [
+        { role: 'system', content: systemPrompt },
+        { role: 'user', content: userMessage },
+      ],
+      max_tokens: 4096,
+    }),
+    buildStreamBody: (model, systemPrompt, userMessage) => ({
+      model,
+      messages: [
+        { role: 'system', content: systemPrompt },
+        { role: 'user', content: userMessage },
+      ],
+      max_tokens: 4096,
+      stream: true,
+    }),
+    parseResponse: (data) => ({
+      content: data.choices?.[0]?.message?.content || '',
+      tokens:
+        (data.usage?.prompt_tokens || 0) +
+        (data.usage?.completion_tokens || 0),
+    }),
+    parseStreamChunk: (line) => {
+      if (line === 'data: [DONE]') return { content: '', done: true }
+      if (!line.startsWith('data: ')) return null
+      try {
+        const json = JSON.parse(line.slice(6))
+        const delta = json.choices?.[0]?.delta?.content || ''
+        const finished = json.choices?.[0]?.finish_reason === 'stop'
+        return { content: delta, done: finished }
+      } catch {
+        return null
+      }
+    },
+  }
+}

 const PROVIDER_CONFIGS = {
-  openai: {
-    url: 'https://api.openai.com/v1/chat/completions',
-    buildHeaders: (apiKey) => ({
-      'Content-Type': 'application/json',
-      Authorization: `Bearer ${apiKey}`,
-    }),
-    // ... rest of config
-  },
+  openai: createOpenAICompatibleConfig('https://api.openai.com/v1/chat/completions'),

-  openrouter: {
-    url: 'https://openrouter.ai/api/v1/chat/completions',
-    buildHeaders: (apiKey) => ({
-      'Content-Type': 'application/json',
-      Authorization: `Bearer ${apiKey}`,
-      'HTTP-Referer': 'https://iloveagents.ai',
-      'X-Title': 'ILoveAgents',
-    }),
-    // ... rest of config
-  },
+  openrouter: createOpenAICompatibleConfig(
+    'https://openrouter.ai/api/v1/chat/completions',
+    {
+      'HTTP-Referer': 'https://iloveagents.ai',
+      'X-Title': 'ILoveAgents',
+    }
+  ),

-  groq: {
-    url: 'https://api.groq.com/openai/v1/chat/completions',
-    buildHeaders: (apiKey) => ({
-      'Content-Type': 'application/json',
-      Authorization: `Bearer ${apiKey}`,
-    }),
-    // ... rest of config
-  },
+  groq: createOpenAICompatibleConfig('https://api.groq.com/openai/v1/chat/completions'),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/llmAdapter.js` around lines 101 - 144, Extract the duplicated
OpenAI-compatible logic into a shared factory function (e.g.,
createOpenAICompatibleProvider or makeOpenAIProviderConfig) and replace the
repeated groq keys (buildHeaders, buildBody, buildStreamBody, parseResponse,
parseStreamChunk) with a call to that factory passing the provider-specific url
('https://api.groq.com/openai/v1/chat/completions'); ensure the factory returns
the same shape (url, buildHeaders, buildBody, buildStreamBody, parseResponse,
parseStreamChunk) so you can reuse it for openai and openrouter as well and
consolidate parsing/token logic in one place.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CHANGELOG.md`:
- Line 15: The KeyboardShortcutsModal component is missing the Groq quick-switch
entry; update src/components/KeyboardShortcutsModal.jsx (the
KeyboardShortcutsModal component/JSX that renders the provider shortcut list) to
include the "Alt + 4" shortcut with the label "Groq" alongside the existing "Alt
+ 1 / 2 / 3" entries so the modal reflects the changelog; if the shortcuts are
generated from an array or constant (e.g., a shortcuts or providers list), add
the Groq item there and ensure the rendered UI displays "Alt + 4 — Groq" and
matches formatting of the other provider entries.

In `@README.md`:
- Line 78: Add an accessible alt attribute to the Groq logo image in the README
table row by updating the <img src="https://console.groq.com/groq-logo.svg"
width="80"/> element to include a descriptive alt (e.g., alt="Groq logo"); also
remove any incidental note about accessing the logo URL if present in the
surrounding text so the table simply displays the image with proper alt text in
the Groq row.
- Line 263: The README provider list is missing 'openrouter' compared to the
JSDoc/provider definitions used by the llmAdapter; update the example provider
enumeration where it shows provider: 'any' (the commented list "'openai' |
'anthropic' | 'gemini' | 'groq' | 'any'") to include 'openrouter' so it reads
"'openai' | 'anthropic' | 'gemini' | 'groq' | 'openrouter' | 'any'"; ensure the
README's agent config example text and any related examples reflect this added
provider string.

In `@src/lib/resolveAgentModel.js`:
- Around line 20-25: The groq model list in resolveAgentModel.js contains
invalid Groq IDs ('openai/gpt-oss-120b' and 'openai/gpt-oss-20b'); update the
groq array (the entries with value 'openai/gpt-oss-120b' and
'openai/gpt-oss-20b') to use valid Groq model identifiers or remove those
entries entirely, and adjust their label strings to match the new model names so
the groq array only contains supported Groq model values (keep the existing
valid entries 'llama-3.3-70b-versatile' and 'llama-3.1-8b-instant' unchanged).

In `@src/pages/WorkflowBuilder.jsx`:
- Around line 37-46: The effect at useEffect(...) that seeds selected agents
references an undefined preselected variable and will throw; update the effect
to read preselected from location.state.preselectedAgents (e.g., const
preselected = location?.state?.preselectedAgents) before using it, or remove
this effect entirely since the other useEffect that declares const preselected =
location.state.preselectedAgents already handles preselection; ensure you still
call setSelectedAgents((prev)=>...) only when a valid preselected array exists
and agents are available.

In `@src/pages/WorkflowRunner.jsx`:
- Line 85: The file calls useAgents() but never imports it and also redeclares
agents locally; import the useAgents hook at the top and remove the local agents
useState and its associated effect (remove the useState([]) that declares agents
and the effect that calls loadAllAgents), then rely solely on the agents
returned from useAgents(); also remove the loadAllAgents import if it becomes
unused. Ensure references to useAgents, agents (from hook), and any
loadAllAgents usage are updated accordingly.

---

Outside diff comments:
In `@src/pages/BattleModeSetup.jsx`:
- Around line 95-106: The initial state for results and prompts is missing an
entry for the new provider "groq", causing undefined access when
PROVIDERS.forEach updates results.groq and rendering reads results[prov.id];
update the useState initializers for results and prompts in BattleModeSetup (the
const [results, setResults] = useState(...) and const [prompts, setPrompts] =
useState(...)) to include a groq key mirroring the shape of the other providers
(e.g., results.groq: { loading: true, content: null, error: null, duration: null
} and prompts.groq: null) so PROVIDERS.forEach and the render loop can safely
access results[prov.id] and prompts[prov.id].
- Around line 214-372: The Prompt Comparison Viewer currently hardcodes
OpenAI/Claude/Gemini columns and omits Groq; update it to render provider
columns dynamically from the PROVIDERS array (or add an explicit Groq column) so
all providers (including "groq") appear. In practice, replace the three
hardcoded blocks with a map over PROVIDERS (use provider.id, provider.label,
provider.textColor) to produce each column, call handleCopyPrompt(provider.id,
prompts[provider.id]) for the copy button, and use copiedProvider ===
provider.id to toggle the Check/Copy UI; also adjust the grid classes (e.g.,
lg:grid-cols-3 xl:grid-cols-4) to accommodate the extra column.

In `@src/pages/HomePage.jsx`:
- Around line 31-48: Import the useAgents hook at the top of the file and
migrate to using it exclusively: remove the local agents useState([]), the
setAgents reference and the useEffect that calls loadAllAgents(), and remove the
loadAllAgents import if no longer used; also delete the duplicate allCategories
declaration so only the useMemo that derives categories from agents (from
useAgents()) remains; ensure any references use the hook's agents value and keep
useDocumentTitle as-is.

In `@src/pages/WorkflowBuilder.jsx`:
- Around line 68-80: The effect references undefined setters setNodes and
setEdges (causing the crash); replace that logic to populate the existing agent
chain state instead or remove it: inside the useEffect that checks
forkedWorkflow, call
setSelectedAgents(JSON.parse(JSON.stringify(forkedWorkflow.agents || []))) to
copy agents from forkedWorkflow (or map forkedWorkflow.nodes -> agents if agents
are stored in nodes), keep the setTitle(`Copy of ${forkedWorkflow.title}`) line,
and remove any setNodes/setEdges calls; ensure forkedWorkflow structure matches
(agents vs nodes/edges) and adjust the mapping accordingly.

---

Nitpick comments:
In `@src/lib/llmAdapter.js`:
- Around line 101-144: Extract the duplicated OpenAI-compatible logic into a
shared factory function (e.g., createOpenAICompatibleProvider or
makeOpenAIProviderConfig) and replace the repeated groq keys (buildHeaders,
buildBody, buildStreamBody, parseResponse, parseStreamChunk) with a call to that
factory passing the provider-specific url
('https://api.groq.com/openai/v1/chat/completions'); ensure the factory returns
the same shape (url, buildHeaders, buildBody, buildStreamBody, parseResponse,
parseStreamChunk) so you can reuse it for openai and openrouter as well and
consolidate parsing/token logic in one place.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ae2f569b-20e9-4047-bc58-a18fdeb2235c

📥 Commits

Reviewing files that changed from the base of the PR and between 380bb0d and a55e174.

⛔ Files ignored due to path filters (2)
  • package-lock.json is excluded by !**/package-lock.json
  • src/assets/groq.svg is excluded by !**/*.svg
📒 Files selected for processing (12)
  • CHANGELOG.md
  • README.md
  • package.json
  • src/components/AgentRunner.jsx
  • src/components/ApiKeyBar.jsx
  • src/lib/llmAdapter.js
  • src/lib/resolveAgentModel.js
  • src/pages/BattleModeSetup.jsx
  • src/pages/HomePage.jsx
  • src/pages/WorkflowBuilder.jsx
  • src/pages/WorkflowRunner.jsx
  • tests/groq-provider.test.js

Comment thread CHANGELOG.md Outdated
Comment thread README.md Outdated
Comment thread README.md
Comment thread src/lib/resolveAgentModel.js
Comment thread src/pages/WorkflowBuilder.jsx Outdated
Comment thread src/pages/WorkflowRunner.jsx Outdated
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 10, 2026
@madsysharma

Copy link
Copy Markdown
Author

Hi @AditthyaSS , please review this updated PR. Thanks.

@madsysharma

Copy link
Copy Markdown
Author

Hi @AditthyaSS , please review this updated PR. Thanks.

@madsysharma

Copy link
Copy Markdown
Author

Hi @AditthyaSS , please review this updated PR. Thanks.

@madsysharma madsysharma force-pushed the feat/groq-support branch 2 times, most recently from 5e5a802 to 3623cdd Compare June 16, 2026 16:42
@madsysharma

Copy link
Copy Markdown
Author

Hi @AditthyaSS , please review this updated PR. Thanks.

@mergify

mergify Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

⚠️ Hey @madsysharma! This PR has a merge conflict that needs to be resolved before we can review or merge it.
Please sync your branch with the latest main and fix the conflicts.
Need help? Check out resolving merge conflicts.
@AditthyaSS

@mergify

mergify Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

⚠️ This branch is out of date with main.
Please click "Update branch" to sync before merging.

@madsysharma

Copy link
Copy Markdown
Author

Hi @AditthyaSS , I have resolved the merge conflicts. Please review this PR. Thank you.

@madsysharma

Copy link
Copy Markdown
Author

Hi @AditthyaSS , I have resolved the merge conflicts and synced the branch. Please review this PR. Thank you.

@mergify

mergify Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

⚠️ Hey @madsysharma! This PR has a merge conflict that needs to be resolved before we can review or merge it.
Please sync your branch with the latest main and fix the conflicts.
Need help? Check out resolving merge conflicts.
@AditthyaSS

@madsysharma

Copy link
Copy Markdown
Author

Hi @AditthyaSS , I have resolved the merge conflicts. Please review this PR. Thank you.

@mergify

mergify Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

⚠️ Hey @madsysharma! This PR has a merge conflict that needs to be resolved before we can review or merge it.
Please sync your branch with the latest main and fix the conflicts.
Need help? Check out resolving merge conflicts.
@AditthyaSS

@mergify

mergify Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

hey @madsysharma! 👋
You changed package.json but package-lock.json was not updated.
Quick check before we review:
→ If you added or removed a package:
Please run npm install and commit the updated package-lock.json too.
Both files need to change together. ✅
→ If you only changed metadata (scripts, description, version etc):
You can safely ignore this message. ✅
Just wanted to make sure nothing was missed! 🙏
@AditthyaSS

@madsysharma

Copy link
Copy Markdown
Author

Hi @AditthyaSS , I have resolved the merge conflicts and have ensured the branch is up to date. Please review this PR as it has been open for a while now. Thanks.

@madsysharma

Copy link
Copy Markdown
Author

Hi @AditthyaSS , I have added package-lock.json as well. Please review this PR. Thanks.

@madsysharma madsysharma force-pushed the feat/groq-support branch 2 times, most recently from 64ac785 to 275ac47 Compare June 21, 2026 14:13
@madsysharma

Copy link
Copy Markdown
Author

Hi @AditthyaSS , please review this PR. Thanks.

@mergify

mergify Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

⚠️ Hey @madsysharma! This PR has a merge conflict that needs to be resolved before we can review or merge it.
Please sync your branch with the latest main and fix the conflicts.
Need help? Check out resolving merge conflicts.
@AditthyaSS

@mergify

mergify Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

⚠️ This branch is out of date with main.
Please click "Update branch" to sync before merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Add Groq API Provider Support

2 participants