Skip to content

feat: add OpenAI and Anthropic cloud AI providers (#74) - #78

Open
divyanshim27 wants to merge 1 commit into
nirvik34:mainfrom
divyanshim27:feat/cloud-ai-providers
Open

feat: add OpenAI and Anthropic cloud AI providers (#74)#78
divyanshim27 wants to merge 1 commit into
nirvik34:mainfrom
divyanshim27:feat/cloud-ai-providers

Conversation

@divyanshim27

@divyanshim27 divyanshim27 commented Jul 24, 2026

Copy link
Copy Markdown

Fixes #74

Summary by CodeRabbit

  • New Features
    • Added AI-powered commit message generation using OpenAI and Anthropic.
    • Added configuration options for enabling AI features, selecting a provider, supplying an API key, and controlling interactive behavior.
    • Supports configurable AI models with sensible defaults.
  • Configuration
    • Existing configuration loading now recognizes the new AI-related settings.

@vercel

vercel Bot commented Jul 24, 2026

Copy link
Copy Markdown

@prince-pokharna is attempting to deploy a commit to the nirvik34's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

.coderabbit.yaml has a parsing error

The CodeRabbit configuration file in this repository has a parsing error and default settings were used instead. Please fix the error(s) in the configuration file. You can initialize chat with CodeRabbit to get help with the configuration file.

💥 Parsing errors (1)
Validation error: Invalid option: expected one of "quiet"|"chill"|"assertive" at "reviews.profile"
⚙️ 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

Walkthrough

Adds OpenAI and Anthropic SDK dependencies, extends configuration with provider settings, and introduces provider classes that generate commit messages from prompts and Git diffs.

Changes

Remote AI providers

Layer / File(s) Summary
Provider configuration and SDK dependencies
src/config/loadConfig.ts, package.json
GitbunConfig now supports AI, interactive mode, provider selection, and an optional API key; OpenAI and Anthropic SDKs are added as dependencies.
Remote provider implementations
src/providers/openai.provider.ts, src/providers/anthropic.provider.ts
Adds provider wrappers for OpenAI Chat Completions and Anthropic Messages API requests, using configurable models and returning trimmed generated text.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning Provider classes and config fields were added, but env-var API key handling, Ollama fallback resolution, docs, and diff truncation are not shown. Add provider-selection logic with Ollama fallback, read keys from OPENAI_API_KEY/ANTHROPIC_API_KEY, document .gitbunrc usage, and truncate diffs to 8000 chars.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding OpenAI and Anthropic cloud AI providers.
Out of Scope Changes check ✅ Passed The changes stay focused on cloud AI provider support, dependency additions, and related config/provider code.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 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 `@src/config/loadConfig.ts`:
- Line 11: Remove apiKey from the GitbunConfig type and keep loadConfig()
limited to returning configuration-file contents. Update the provider factory to
resolve OPENAI_API_KEY and ANTHROPIC_API_KEY directly from the environment
instead of reading an API key from GitbunConfig.
- Around line 8-11: Update the src/index.ts runtime flow around
isOllamaRunning() and enhanceCommit() to resolve the configured provider and
route execution through the selected OpenAI or Anthropic implementation; retain
Ollama only when provider is unset or unsupported, and ensure the apiKey is
passed to the chosen provider as required.
- Around line 8-11: Update the cosmiconfig explorer used by the configuration
loader to include `.gitbunrc` in its searchPlaces, while preserving the existing
supported formats. Add a config-loading test covering the documented `.gitbunrc`
filename and verifying its fields, including provider and apiKey, are loaded.

In `@src/providers/anthropic.provider.ts`:
- Around line 13-16: Update the Anthropic messages.create call to pass prompt
through the top-level system parameter and make the user message contain only
the untrusted diff content. Remove the prompt interpolation from the user
message while preserving the existing model and token settings.

In `@src/providers/openai.provider.ts`:
- Around line 12-17: Apply the shared 8,000-character diff cap before
constructing the user message in generateCommitMessage for
src/providers/openai.provider.ts (lines 12-17) and the corresponding Anthropic
request in src/providers/anthropic.provider.ts (lines 12-16). Ensure both
providers interpolate only the truncated diff while preserving the existing
prompt and request structure.
🪄 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: 8246fd23-8d63-41fa-9eb4-70ce836a4256

📥 Commits

Reviewing files that changed from the base of the PR and between 07b25af and a1d6153.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • package.json
  • src/config/loadConfig.ts
  • src/providers/anthropic.provider.ts
  • src/providers/openai.provider.ts

Comment thread src/config/loadConfig.ts
Comment on lines +8 to +11
ai?: boolean;
interactive?: boolean;
provider?: 'ollama' | 'openai' | 'anthropic'; // add this
apiKey?: string;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Wire provider selection into the runtime path.

The new fields are never consumed: the supplied src/index.ts flow still calls isOllamaRunning() and enhanceCommit() directly. Selecting openai or anthropic therefore has no effect. Add provider resolution and retain Ollama only as the fallback.

🤖 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/config/loadConfig.ts` around lines 8 - 11, Update the src/index.ts
runtime flow around isOllamaRunning() and enhanceCommit() to resolve the
configured provider and route execution through the selected OpenAI or Anthropic
implementation; retain Ollama only when provider is unset or unsupported, and
ensure the apiKey is passed to the chosen provider as required.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)loadConfig\.ts$|package\.json|README|\.gitbunrc|smartcommit' || true

echo "== config loader candidates =="
fd -a -i 'loadConfig|config' . | sed 's#^\./##' | head -50

echo "== loadConfig.ts =="
for f in $(fd -i 'loadConfig\.ts$' .); do
  echo "--- $f"
  wc -l "$f"
  cat -n "$f"
done

echo "== searchPlaces / cosmiconfig usages =="
rg -n "cosmiconfig|searchPlaces|smartcommit|gitbunrc|\\.git" -S . --glob '!node_modules' --glob '!dist' --glob '!build' || true

echo "== package manifests =="
for f in $(fd -i 'package\.json$' .); do
  echo "--- $f"
  sed -n '1,220p' "$f"
done

Repository: nirvik34/gitbun

Length of output: 8530


🌐 Web query:

cosmiconfig 9.0 searchPlaces default .gitignore dotfiles

💡 Result:

In cosmiconfig 9.0, the searchPlaces option defines the list of filenames and paths the library checks when searching for a configuration [1][2]. Cosmiconfig does not have any built-in logic to ignore or respect.gitignore files; it simply attempts to locate and load the configuration files specified in the searchPlaces array [1][3]. The default searchPlaces configuration includes various rc-style files and a.config/ subdirectory [1][3]. The default list is as follows: [ 'package.json', .${moduleName}rc, .${moduleName}rc.json, .${moduleName}rc.yaml, .${moduleName}rc.yml, .${moduleName}rc.js, .${moduleName}rc.ts, .${moduleName}rc.mjs, .${moduleName}rc.cjs, .config/${moduleName}rc, .config/${moduleName}rc.json, .config/${moduleName}rc.yaml, .config/${moduleName}rc.yml, .config/${moduleName}rc.js, .config/${moduleName}rc.ts, .config/${moduleName}rc.mjs, .config/${moduleName}rc.cjs, ${moduleName}.config.js, ${moduleName}.config.ts, ${moduleName}.config.mjs, ${moduleName}.config.cjs ] In this list, {moduleName} is the name provided to the cosmiconfig explorer instance [1][4]. The library searches for these files in the current working directory by default (in version 9.0, the default searchStrategy is 'none', meaning it does not traverse upward by default) [5][3][6]. If you need to exclude specific files, you must manage that at the project or file system level, as cosmiconfig will attempt to load any file matching these patterns if it exists in the designated search paths [1][3].

Citations:


🌐 Web query:

cosmiconfig 9 searchPlaces default file extensions

💡 Result:

In Cosmiconfig 9, the default searchPlaces consist of a predefined list of files that the library searches for when looking for configuration [1][2]. The list includes files in the current directory and a .config/ subdirectory, using the moduleName provided to the library [1][2]. The default search places are [1][2]: * package.json (parsed for a specific property) *.${moduleName}rc *.${moduleName}rc.json *.${moduleName}rc.yaml *.${moduleName}rc.yml *.${moduleName}rc.js *.${moduleName}rc.ts *.${moduleName}rc.mjs *.${moduleName}rc.cjs *.config/${moduleName}rc *.config/${moduleName}rc.json *.config/${moduleName}rc.yaml *.config/${moduleName}rc.yml *.config/${moduleName}rc.js *.config/${moduleName}rc.ts *.config/${moduleName}rc.mjs *.config/${moduleName}rc.cjs * ${moduleName}.config.js * ${moduleName}.config.ts * ${moduleName}.config.mjs * ${moduleName}.config.cjs Each item in this list must have a corresponding loader configured in the loaders option that matches its file extension [1][2]. Common extensions are covered by default loaders, while files without extensions (e.g.,.${moduleName}rc) are handled by the noExt loader key [1][3]. Additionally, when package.json is included, Cosmiconfig parses it as JSON and loads a specific property (defaulting to the moduleName) rather than the entire file [1][2].

Citations:


Add .gitbunrc to the cosmiconfig search paths.

cosmiconfig("smartcommit") uses an explorer named smartcommit, so with the default searchPlaces it will only look for .smartcommitrc* / smartcommit.config.*; .gitbunrc will not be loaded and these new config fields are ignored. Also add a config-loading test for the documented .gitbunrc file.

🤖 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/config/loadConfig.ts` around lines 8 - 11, Update the cosmiconfig
explorer used by the configuration loader to include `.gitbunrc` in its
searchPlaces, while preserving the existing supported formats. Add a
config-loading test covering the documented `.gitbunrc` filename and verifying
its fields, including provider and apiKey, are loaded.

Comment thread src/config/loadConfig.ts
ai?: boolean;
interactive?: boolean;
provider?: 'ollama' | 'openai' | 'anthropic'; // add this
apiKey?: string;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Keep API keys out of GitbunConfig.

loadConfig() returns configuration-file contents unchanged, so apiKey?: string permits secrets to be stored in .gitbunrc, contradicting the environment-only requirement. Resolve OPENAI_API_KEY/ANTHROPIC_API_KEY in the provider factory instead.

🤖 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/config/loadConfig.ts` at line 11, Remove apiKey from the GitbunConfig
type and keep loadConfig() limited to returning configuration-file contents.
Update the provider factory to resolve OPENAI_API_KEY and ANTHROPIC_API_KEY
directly from the environment instead of reading an API key from GitbunConfig.

Comment on lines +13 to +16
const response = await this.client.messages.create({
model: this.model,
max_tokens: 200,
messages: [{ role: 'user', content: `${prompt}\n\nGit diff:\n\`\`\`\n${diff}\n\`\`\`` }],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail
npm view `@anthropic-ai/sdk`@0.115.0 version

Repository: nirvik34/gitbun

Length of output: 310


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "== file excerpt =="
sed -n '1,120p' src/providers/anthropic.provider.ts

echo
echo "== package versions / constraints =="
for f in package.json package-lock.json pnpm-lock.yaml yarn.lock; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    rg -n '"`@anthropic-ai/sdk`"|anthropic' "$f" || true
  fi
done

echo
echo "== occurrences of this provider / prompt diff usage =="
rg -n "AnthropicProvider|anthropic\\.provider|max_tokens: 200|this\\.client\\.messages\\.create|messages: \\[\\{ role: 'user', content" src package.json package-lock.json pnpm-lock.yaml yarn.lock || true

Repository: nirvik34/gitbun

Length of output: 1724


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "== installed anthropic SDK type if present =="
node -e "const fs=require('fs'); const p='node_modules/@anthropic-ai/sdk/resources/messages.d.ts'; console.log(fs.existsSync(p))?fs.readFileSync(p,'utf8').slice(0,1200):p+' not present'" 2>/dev/null || true

echo
echo "== local anthropic types if present =="
if [ -d node_modules/@anthropic-ai/sdk ]; then
  find node_modules/@anthropic-ai/sdk -maxdepth 3 -type f | sed -n '1,80p'
fi

Repository: nirvik34/gitbun

Length of output: 5036


🌐 Web query:

Anthropic Messages API system parameter documentation untrusted content safety

💡 Result:

To safely handle untrusted content when using the Anthropic Messages API, you must leverage structural separation at the API level [1][2]. The Messages API is designed to distinguish between system instructions and user-provided data, which is critical for preventing prompt injection attacks [2]. Key security practices for the Messages API: 1. Use the Dedicated System Parameter: The API provides a top-level system parameter specifically for instructions that define the model's behavior, goal, or role [3][4][5]. You must use this parameter for your system instructions rather than attempting to include them within the messages array or concatenating them with user input [3][2][6]. 2. Maintain Architectural Boundary for Untrusted Input: All untrusted content—such as data from web pages, user uploads, third-party APIs, or tool outputs—must be placed within the messages array, specifically using the user role [1][7]. Do not interpolate untrusted content into the system parameter or mix it with your application's instructions [2]. For Claude 3.7 and later, the API enforces a token-level boundary that prevents user messages from syntactically overriding system instructions, provided the inputs are correctly separated at the call level [2]. 3. Handle Tool Outputs as Untrusted: When using tools, treat all tool outputs as untrusted content [7]. Keep these outputs inside tool_result blocks rather than placing them in the system prompt or plain text blocks [7]. Anthropic recommends screening tool outputs for injection attempts before passing them to the model, which can be done by using a smaller, lightweight model (e.g., Claude Haiku) to evaluate the tool output for adversarial commands before it is processed by the main agent [8]. 4. Leverage Enterprise Trust & Safety: For enterprise-tier users, additional "Trust & Safety Configuration" is available [9]. This feature allows you to inject organizational policies and audit requirements via request headers, which Anthropic's safety layer uses to evaluate both the prompt and the response [9]. If a safety violation is detected, the API will return a stop_reason of safety_violation, which must be handled programmatically in your application logic, as the API may still return a 200 OK status [9]. By strictly enforcing the separation between system-defined instructions and untrusted user/tool data, you shift the security burden from relying on model robustness alone to utilizing the API's structural protections [2].

Citations:


Pass system instructions via Anthropic’s top-level system parameter.

prompt drives the provider behavior, while diff is untrusted tool output. Keep them split: system: prompt plus a user message with the git diff only.

🤖 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/providers/anthropic.provider.ts` around lines 13 - 16, Update the
Anthropic messages.create call to pass prompt through the top-level system
parameter and make the user message contain only the untrusted diff content.
Remove the prompt interpolation from the user message while preserving the
existing model and token settings.

Comment on lines +12 to +17
async generateCommitMessage(diff: string, prompt: string): Promise<string> {
const response = await this.client.chat.completions.create({
model: this.model,
messages: [
{ role: 'system', content: prompt },
{ role: 'user', content: `Git diff:\n\`\`\`\n${diff}\n\`\`\`` },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Apply the 8,000-character diff cap consistently across cloud providers.

Both implementations interpolate the complete diff into their requests, violating the shared PR requirement.

  • src/providers/openai.provider.ts#L12-L17: truncate diff before constructing the OpenAI user message.
  • src/providers/anthropic.provider.ts#L12-L16: truncate diff before constructing the Anthropic user message.
📍 Affects 2 files
  • src/providers/openai.provider.ts#L12-L17 (this comment)
  • src/providers/anthropic.provider.ts#L12-L16
🤖 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/providers/openai.provider.ts` around lines 12 - 17, Apply the shared
8,000-character diff cap before constructing the user message in
generateCommitMessage for src/providers/openai.provider.ts (lines 12-17) and the
corresponding Anthropic request in src/providers/anthropic.provider.ts (lines
12-16). Ensure both providers interpolate only the truncated diff while
preserving the existing prompt and request structure.

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

Labels

None yet

Projects

None yet

2 participants